MySQL学习——分区表

MySQL存储引擎现状及发展趋势

MySQL官网有这样一句话:

As of MySQL 5.7.17, the generic partitioning handler in the MySQL server is deprecated, and is removed in MySQL 8.0, when the storage engine used for a given table is expected to provide its own (“native”) partitioning handler. Currently, only the InnoDB and NDB storage engines do.

大意为MySQL 8.0中将会移除普通的分区而只支持存储引擎内置分区的方式。
如下文所示,即为普通的分区方式:

CREATE TABLE users (  
     uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,  
     name VARCHAR(30) NOT NULL DEFAULT '',  
     email VARCHAR(30) NOT NULL DEFAULT ''  
)  
PARTITION BY HASH (uid) PARTITIONS 4 (  
     PARTITION p0  
     DATA DIRECTORY = '/data0/data'  
     INDEX DIRECTORY = '/data1/idx',  
  
     PARTITION p1  
     DATA DIRECTORY = '/data2/data'  
     INDEX DIRECTORY = '/data3/idx',  
  
     PARTITION p2  
     DATA DIRECTORY = '/data4/data'  
     INDEX DIRECTORY = '/data5/idx',  
  
     PARTITION p3  
     DATA DIRECTORY = '/data6/data'  
     INDEX DIRECTORY = '/data7/idx'  
);

这里我们可以有一个最基本的判断逻辑,假如数据库表没有指定存储引擎,即可认为是MySQL不建议使用的分区方式。当在5.7版本中使用时,MySQL将提示:

The partition engine, used by table 'table_name', is deprecated and
will be removed in a future release. Please use native partitioning instead.

用户在这时为数据库表指定存储引擎InnoDB或NDB即可。

ALTER TABLE table_name ENGINE = INNODB;

分区表的优势

  • 分区使得可以将一个表中的更多数据存储在单个磁盘或文件系统分区上。
  • 由于满足给定WHERE子句的数据只能存储在一个或多个分区上,因此可以将搜索中的剩余分区自动排除,可以大大优化一些查询。
  • 此外,MySQL 5.7支持查询的显式分区选择。 例如,SELECT * FROM t PARTITION(p0,p1)WHERE c <5仅选择与WHERE条件匹配的分区p0和p1中的那些行。 在这种情况下,MySQL不会检查表t的任何其他分区; 当您已经知道要检查的分区或分区时,这可以大大加快查询速度。
  • 涉及聚合函数(如SUM()和COUNT()的查询可以轻松并行化。
  • 凭借扩展数据实现更大的查询吞吐量,可以查找多个磁盘。

分区表的基本概念

对用户而言,分区表是一个独立的逻辑表,但是底层由多个物理子表组成。实现分区的代码实际上是对一组底层表的句柄对象(Handler Object)的封装。对分区表的请求,都会通过句柄对象转化成对存储引擎的接口调用。所以分区对于SQL层来说是一个完全封闭底层实现的黑盒子,对应用是透明的,但是从底层的文件系统也就很容易发现,每个分区表都有一个使用#分隔命名的表文件。
在下面的场景中,分区可以起到非常大的作用:

  • 表非常大以至于无法全部放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。
  • 分区表的数据更容易维护。例如,想批量删除大量数据可以使用清除整个分区的方式
  • 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。
  • 可以使用分区表来避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问、ext3文件系统的inode锁竞争等。

分区表本身也有一些限制:

  • 一个表最多只能有1024个分区
  • 在MySQL5.1中,分区表达式必须是整数,或者是返回整数的表达式。在MySQL5.5中,某些场景中可以直接使用列表来进行分区。
  • 如果分区字段中有主键或者唯一索引的列,那么 所有主键列和唯一索引列都必须包含进来
  • 分区表中无法使用外键约束。

分区表的原理

分区表由多个相关的底层表实现,这些底层表也是由句柄对象(Handler object)表示,所以我们也可以直接访问各个分区。存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分区表的索引只是在各个底层表上各自加上一个完全相同的索引。从存储引擎的角度来看,底层表和一个普通表没有任何不同,存储引擎也无须知道这是一个普通表还是分区表的一部分。
分区表的操作逻辑:
SELECT查询
当查询一个分区表的时候,分区表先打开并锁住所有的底层表,优化器先判断是否可以过滤部分分区,然后再调用对应的存储引擎访问各个分区的数据。
INSERT操作
当写入一条记录时,分区层先打开并锁住所有的底层表,然后确定哪个分区接受这条记录,再将记录写入对应底层表。
DELETE操作
当删除一条记录时,分区层先打开并锁住所有的底层表,然后确定数据对应的分区,最后对相应底层表进行删除操作。
UPDATE操作
当更新一条记录时,分区层先打开并锁住所有的底层表,MySQL先确定需要更新的记录在哪个分区,然后取出并更新,再判断更新后的数据应该放在哪个分区,最后对底层表进行写入操作,并对原数据所在的底层表进行删除操作。

分区表的类型

MySQL支持多种分区表。用的最多的是根据范围进行分区;还支持键值、哈希和列表分区。

例,根据范围进行分区:
CREATE TABLE sales (
    id INT AUTO_INCREMENT,
    amount DOUBLE NOT NULL,
    order_day DATETIME NOT NULL,
    PRIMARY KEY(id, order_day)
) ENGINE=Innodb PARTITION BY RANGE(YEAR(order_day)) (
    PARTITION p_2010 VALUES LESS THAN (2010),
    PARTITION p_2011 VALUES LESS THAN (2011),
    PARTITION p_2012 VALUES LESS THAN (2012),
    PARTITION p_catchall VALUES LESS THAN MAXVALUE);

什么情况下会出问题

  • NULL值会使过滤无效
  • 分区列和索引列不匹配
  • 选择分区的成本可能很高
  • 打开并锁住所有底层表的成本可能很高
  • 维护分区的成本可能很高

使用分区表的限制:

  • 所有分区都必须使用相同的存储引擎
  • 分区函数中可以使用的函数和表达式也有一些限制
  • 某些存储引擎不支持分区
  • 对于MyISAM的分区表,不能再使用LOAD INDEX INTO CACHE操作
  • 对于MyISAM表,使用分区表时需要打开更多的文件描述符。

参考文献

  1. 《高性能MySQL》
  2. MySQL分区(官网)
  3. 原文链接
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容