首页 > 其他分享 >innodb到底什么时候进行分表操作?

innodb到底什么时候进行分表操作?

时间:2023-02-01 13:46:29浏览次数:42  
标签:到底 int 查询 索引 innodb 数据量 分表

一,一个技术人常被问到的问题

Q:一张表数据量达到多大才需要进行分表的操作?
A:一些八股文的说法是,达到xxx条数据就需要进行分表的操作了
通常我们会使用一个简单的指标 - “数据量”,来判断是否需要开始进行分表操作,如上面这个问题
很明显,在不同条件下这个问题会有不同的回答,并不能一概而论

通常大部分人认为,数据量的大小会明显影响查询的耗时

所以首先要明白一个问题,数据量越大,查询就会越慢吗?
看下面这个例子:
1,mysql5.7下创建四张表, 分别插入 20 万 , 50万 , 150万, 1500万数据

CREATE TABLE `t1` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `t2` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `t3` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
CREATE TABLE `t4` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
create procedure idata1()
begin
  declare i int;
  set i=1;
  while(i<=200000) do
    insert into t1 values(i,i);
    set i=i+1;
  end while;
end;;

call idata1();

# 同样的方法再给t2 , t3, t4 插入数据
# 也可以使用load data的方式导入,会快很多,这里不再讨论

分别对这几张表执行相同的查询sql, 观察各自的执行时间
测试过程中最好将query_cache_type 设置为OFF ,防止重复执行的结果被缓存干扰
如果你是8.0以上的mysql,默认去除了查询缓存模块,可以不用设置,mysql5.7版本默认也是OFF的
使用 show variables like '%query_cache_type%'查看变量的值
使用 **set GLOBAL **query_cache_type=0;** 关闭缓存功能**

2, 在没有添加索引的情况下, 相同的sql,分别执行了(80ms, 130ms, 430ms, 3550ms)
image.png
可以看到,似乎数据量越大,查询的耗时越多?
那么我们加上索引呢? 索引对于查询的优化效果不言而喻,我们分别给四张表加上c字段索引,再次查询
image.png
可以发现,加上索引后,在查询速度上几乎没有什么区别,都非常快
我们可以得出一个结论:
对于可以命中或者使用索引的查询,无论表大小,对查询速度的影响微乎其微
对于无法命中或者使用索引的查询,表的数据量越大,对查询速度的影响越大
当然,一切都建立在合理的索引与数据结构之上

虽然以上的案例明显没有达到单表的极限,但我们依然可以总结出分表的使用场景:
(1)可以通过sql优化手段解决的问题都没必要进行分表等复杂操作
(2) 单表数据量过大,且无法通过其他手段进一步优化,这个时候,才需要考虑分表


二,从底层数据结构,分析单表的瓶颈

上面说到单表数据量过大,而且无法通过常规的手段进行优化的情况,我们需要从底层的存储结构进行分析
回顾一下innodb的相关概念:

  • innodb使用b+树模型对数据进行存储,每一条索引对应一颗b+树,每颗树由叶子节点和非叶子节点组成,前者只做索引使用,后者存放具体的数据
  • 聚簇索引和非聚簇索引:区别是前者的叶子节点会存放整条数据的所有字段的值,后者除了存放索引字段的值外,只会存主键的值,主键索引是聚簇索引,其他索引都是非聚簇索引
  • 在执行查询语句时,会根据b+树的结构一步步向下查找,主要的耗时集中在每一次的磁盘io(也就是将非叶子节点的数据load到内存中的耗时,根据索引内容查找下一个节点的耗时相比之下可以忽略不计)

不难理解,随着树的增高,每次查询都会增加磁盘io的次数,导致速度变慢

通常情况下b+树的高度在3层,尽量确保每次查询的磁盘io的次数在 2 次,(根结点会被load到内存中常驻),以便保持最佳性能
那么** **
一颗高度为3的b+树,最多能够保存多少数据呢?
innodb页文件: innodb的最小储存单元,也称为页,每一个后缀为 ibd 的文件,默认大小都为16k (也可以指定为64k,对应变量名为 innodb_page_size , 这里不做讨论),所有数据都存放在这样的文件中
上面说过,非叶子节点存放的是索引数据,具体包括(索引键值+指向下一个节点的指针),如果这里的键为bigint类型,占用8字节,innodb指针占用6字节, 总共 14 字节, 那么可以算出,一个页文件可以存放
16*1024 / 14 = 1170 个非叶子节点, 每个非叶子节点作为索引指向一个页文件

可以得出,共有 1170 * 1170 个页文件可以存放具体的数据,每个页文件为16k,如果一条数据预估为1k,那么一个页文件可以存放16条数据

所以得到结论, 一个高度为 3 的b+树, 主键为bigint(8字节), 单条数据大小为1kb, 最多可以存放:
((16*1024)bytes / (8+6)bytes)**2 * (16 / 1) = 1170**2 * 16 = 21902400
大约2000W条数据

一般结构比较简单的表,单条数据也很少会达到1kb的大小,所以我们经常会发现,即便一些表数据量达到几亿速度也依然不会被影响,这里针对的是主键索引对应的b+树

如果是一颗联合索引的b+树,很显然,在数据量增多的后,可能会提前写满数据或者使树变高,从而导致查询性能降低

二,总结

对于是否需要进行分表:
在现有手段能够优化性能的时候,没必要进行分表操作,分表是在数据量达到单表瓶颈的时候所采用的优化手段
在保持最大性能的前提下,可以提前预估单表的最大数据量:
在保证树高越矮的前提的下,依据业务表结构预估出单表最大数据条数,可以提前制定好分表计划

依据表字段,表结构,索引等是否完善,并与当前的业务,表数据量结合起来分析,判断你是否需要分表,以及如何进行分表

标签:到底,int,查询,索引,innodb,数据量,分表
From: https://www.cnblogs.com/xiuneng/p/17082266.html

相关文章

  • 云服务到底是什么?
    1虚拟化技术想要了解云服务,首先需要知道什么是虚拟化技术。在​​计算机​​​中,​​虚拟化​​​(​​英语​​​:Virtualization)是一种资源管理技术,是将计算机的各种实体资......
  • vue.js客服系统实时聊天项目开发(十五)实现聊天界面滚动到底部
    在进入在线聊天界面以后,不管是历史消息,还是实时消息,都需要让最新消息展示出来。因此需要把聊天界面滚动到最底部  //滚动到底部scrollBot......
  • SQLSERVER 的 nolock 到底是怎样的无锁?
    一:背景1.讲故事相信绝大部分用SQLSERVER作为底层存储的程序员都知道nolock关键词,即使当时不知道也会在踩过若干阻塞坑之后果断的加上nolock,但这玩意有什么注意事项......
  • 千万级数据,如何做性能优化?分库分表、Oracle分区表?
    大家好,我是哪吒,最近项目有一个新的需求,​​按月建表,按天分区​​。不都是分库分表吗?怎么又来个分区?让我们一起,一探究竟,深入理解一下Oracle分区表技术,实现快速入门,丰富个人简......
  • python语法到底多精妙?八大核心语句,带你深度了解
    Python是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视Python语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现Python语法之精妙的十......
  • 人人都在聊的云原生数据库Serverless到底是什么?
    摘要:华为云数据库营销专家TonyChen和华为云数据库高级产品经理佳恩开展了一场关于云原生数据库与Serverless结合的直播对话。云计算的迅猛发展推动了数据库的变革,云原生数......
  • 人人都在聊的云原生数据库Serverless到底是什么?
    摘要:华为云数据库营销专家TonyChen和华为云数据库高级产品经理佳恩开展了一场关于云原生数据库与Serverless结合的直播对话。云计算的迅猛发展推动了数据库的变革,云原生......
  • SQLSERVER 事务日志的 LSN 到底是什么?
    SQLSERVER事务日志的LSN到底是什么? 一:背景1.讲故事大家都知道数据库应用程序 它天生需要围绕着数据文件打转,诸如包含数据的 .mdf,事务日志的 .ldf,很多时候深......
  • Pandas的join和merge到底哪个快
    大家好,我是小小明。上次我们的云朵君同学在不严谨的测试下,得出了join可以比merge快5倍的结论。虽然默认参数用法下,join确实比merge快一些,但实际上join并不见得会比merge快。......
  • MySql分库分表
    MySql分库分表分库分表策略当数据量达到一定程度时,我们出于性能考虑就需要将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果......