MySQL优化器特性(九)行数评估

俊达3年前技术文章2007

查询的行数在成本计算中起了很重要的作用:

1、row_evaluate_cost和行数直接相关

2、需要访问多少索引页面,和行数直接相关。根据页面大小和平均索引条目长度计算每个索引页面的记录数,根据记录数计算索引页面数。

3、需要回表访问多少表的页面,和行数直接相关。mysql认为range访问时,每一行记录都需要访问一个数据页面。

4、主键范围扫描页面数,和行数直接相关。


那么如何精确的评估查询需要访问的记录数呢?

InnoDB中有一个index dive的特性,可以根据range区间范围,直接到索引中统计满足条件的记录数。


index dive

index dive统计一个索引区间范围内记录数的逻辑大致如下(btr_estimate_n_rows_in_range):

1、找到范围的下界

2、扫描数据,直到范围的上界,或者扫描的页面数超出限制(10个页面?)

3、如果范围内的页面数不多,则可以精确统计出需要访问的记录数。

4、如果范围内的页面数超过扫描限制,则根据已经扫描的页面,计算平均每页记录数,乘以页面数量,得到一个预估的纪录数。







页面的数量可以通过统计上一层branch页面中的索引条目数得到。根据索引结构的特征,索引页面中的一行记录指向下一个层级中的一个page,根据索引页面中的记录数,就可以得到下一个层级中相应的页面数:


如果一个SQL中涉及到的range的数量特别多(比如in列表中传入了大量数据),则统计每一range的记录数就会消耗大量成本,mysql有一个参数eq_range_index_dive_limit,用于限制优化器进行index dive的开销。如果一个SQL中的range数超过了eq_range_index_dive_limit,优化器就不会通过index dive来评估记录数,转而使用表和索引的统计信息,或者使用经验公式来评估记录数。

mysql 8.0中,eq_range_index_dive_limit默认值为200。



相关文章

MySQL运维实战(4.8) SQL_MODE之NO_ENGINE_SUBSTITUTION

开启NO_ENGINE_SUBSTITUTION,建表时如果指定的存储引擎不可用或不存在,SQL报错。否则会使用默认的存储引擎替换。如果不设置NO_ENGINE_SUBSTITUTION,建表时指定的...

MySQL运维实战之备份和恢复(8.7)将数据库恢复到指定时间点的另外一种方法

使用mysql原生复制功能实现时间点恢复使用mysqlbinlog解析并执行binlog是实现mysql时间点恢复的一种常用的方法。这里提供另外一种实现时间点恢复的方法:使用mysql的复制功能来实现...

MySQL运维实战之备份和恢复(8.5)xtrabackup恢复增量备份

恢复增量备份时,需要先对基础全量备份进行恢复,然后再依次按增量备份的时间进行恢复。这个例子中,相关备份文件的目录结构如下:/data/backup ├── full │ &nb...

MySQL运维实战之ProxySQL(9.2)ProxySQL安装和配置

proxysql安装proxysql提供了各个linux发行版的安装包,我们可以使用操作系统的包管理系统来安装proxysql。这里我们以CentOS 7为例:1、从github下载安装包根据OS版本...

MySQL运维实战(5.1) 字符和编码的基本概念

MySQL运维实战(5.1) 字符和编码的基本概念

字符和编码字符字符是符号,是人们用于交流的各类符号,如26个英文字母、汉字、标点符号、数学运算符、其他语言的字母和符号。编码编码是计算机中以二进制方式存储字符的方式。字符集字符集是字符和编码的映射表。...

MySQL运维实战之备份和恢复(8.2)xtrabackup备份到云端(OSS)

xtrabackup工具中有一个xbcloud程序,可以将数据库直接备份到S3对象存储中,本地不落盘。这里介绍将数据库直接备份到OSS的一种方法。具体方法如下:1、准备OSS我们使用ossutil工具...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。