mysql分表真得能提升查询性能吗

首先将存储引擎限定在innodb

2种方式分表

  1. 水平分表,根据某一列或者某几列将表按行分割到多张表中,达到减少每张表行数的目的
  2. 垂直分表,将表的一些列拆分到多张表中,达到减少每张表列数的目的

分表真得能提升查询性能吗

分表分库

如果将不同的表分到多个库多个机器上,那一定是能提升性能的,毕竟你花钱买机器了,总的可用CPU和内存高了。这种情况不必考虑。

分表不分库

如果所有分表都在同库同机器上,每个表的查询都共用CPU和内存,性能是怎么提升的?

1. 有索引的情况

例如这条查询 select * from user_feeds where uid = ? ,且uid字段上有二级索引,查询步骤为:

  1. 确定索引的扫描范围,即找到B+树上uid=X的最左叶子节点和最右叶子节点,可能(不考虑已经缓存到buffer pool中)需要进行的最大IO次数为4(4层b+树已经可以存放巨量的数据了,一般千万级的是3层)
  2. 遍历扫描范围内的索引数据,取出主键id
  3. 通过主键id进行回表查询,IO次数最大值为扫描范围内索引记录数量乘以聚簇索引中定位一条记录的IO次数(B+树层数)

通过以上步骤可以看出,查询的主要成本为:确定索引扫描范围的IO次数(最大为4)、遍历扫描范围内索引数据的CPU占用(与扫描范围内记录数成正比)、回表IO次数(与扫描范围内记录数成正比,且受聚簇索引B+树层数影响)。所以查询的成本主要取决于uid=X对应的记录数量和索引B+树的层数。

来看一下分表后的查询成本:

  1. 首先是确定索引扫描范围的IO次数由B+树的层数决定,大部分情况下分表是会降低单表的树的层数,例如由4层降到3层,可以减少一次IO
  2. 扫描范围内记录数不会变,所以遍历扫描范围内索引数据的CPU占用不变
  3. 回表IO次数,由于扫描范围内的记录数不变,回表次数也不变,通过聚簇索引定位具体记录数据IO次数可能会减少(同步骤1中普通索引确定扫描范围的IO次数同理)

可见分表后主要的差别在于确定索引扫描范围的IO次数和回表IO次数,即分表后B+树的层数变化,变化范围为0到3。对于不需要回表的查询,差别在于用到的索引B+树层数变化导致的确定扫描范围的IO次数变化;对于需要回表的查询,除了确定扫描范围的IO次数变化,还有回表IO次数变化(回表IO次数变化=记录数X聚簇索引B+树层数变化)。

2. 全表扫描的情况

以上是有二级索引的情况,如果没有索引,需要全表扫描时,扫描整个聚簇索引的成本:加载数据页到内存的IO次数(聚簇索引的页面数)、扫描记录的CPU占用(整个聚簇索引的记录数量)。分表以后所有表总的记录数量不变,页面数量也可以认为不变。所以全表扫描的查询性能分表与不分表也不会有什么差别。

3. 垂直分表能带来性能提升吗

垂直分表,表记录数不会改变,每条记录数据占用空间会变小,从而导致单表聚簇索引每个数据页可以存储的记录变多,聚簇索引的数据页数量变少,原来uid=X的记录可能分布在N个数据页上,分表后uid=X的记录分布在的数据页数量<=N。也就是减少回表IO的次数。

但是,这种情况只限于合理的垂直分表,也就是select的列可以落在同一张表中。

4. 分表对写操作的性能提升(待续)

innodb索引数据大小估算

理论估算

索引列:uid、created_at
单条记录大小 uid4字节、created_at4字节、主键post_id8字节,页号6字节 共22字节
单页可以存放的记录数 16kb(16384)/22 = 744,去除掉一些其他信息(header、槽信息),再去除一些碎片(删除造成的、没填满造成的),姑且认为每页存放500条记录

如果总的记录条数为5000w,那么需要的叶子节点数量为 5000w/500 = 10w,B+树需要两层(500X500 = 25w)
索引叶子节点占用空间大小为 10wX16kb = 1.6GB
索引目录节点占用空间大小为 500X16kb = 8M

实际业务场景中

测试环境

单条记录大小 24
单页可以存放的记录数 682

与理论估算相近

// innodb统计信息查询方法,注意sum_of_other_index_sizes代表的是所有二级索引占用的页面数
select n_rows,'Secondary Indexes' AS 'BTrees',sum_of_other_index_sizes * 16384 AS Bytes,ROUND(sum_of_other_index_sizes * 16384 / n_rows) AS 'Bytes/row',sum_of_other_index_sizes AS Pages,ROUND(n_rows / sum_of_other_index_sizes) AS 'Rows/page' FROM innodb_table_stats where database_name = 'stt_post' and table_name = 'posts'
生产环境有限的信息
99.png

索引空间大小19.38GB,生产环境二级索引数量16个,平均每个索引空间大小约1.1GB,比理论估算还小一些。

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

推荐阅读更多精彩内容