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

俊达2年前技术文章1168

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

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运维实战(5.6) 字符集设置对mysqldump的影响

mysqldump不指定字符集不指定字符集时,默认使用了utf8。可能和环境有关系。mysqldump -uroot test test_load >&n...

 MySQL运维实战(1.3)安装部署:源码编译安装

MySQL运维实战(1.3)安装部署:源码编译安装

源码编译安装通常不需要自己编译mysql源码,编译的mysql和二进制包的内容基本一致。当然有些时候可能会需要采用源码编译的方式安装,安装一些非标准版本的mysql安装一些社区的patch、bugfi...

MySQL运维实战(3.2) 常见数据库连接失败问题排查

如果数据库连接失败,可以从如下几方面来排查:1、客户端到服务端的网络是否畅通,服务端端口是否能连通。使用ping、telnet等工具探测服务端的端口是否能访问。[root@box3 ~]#&...

MySQL运维实战(4.6) SQL_MODE之NO_BACKSLASH_ESCAPES

设置NO_BACKSLASH_ESCAPES后,反斜杠(\)不作为转义符。不设置NO_BACKSLASH_ESCAPES时,反斜杠(\)用来转义后一个字符mysql> create&n...

MySQL运维实战(2.1) 登录失败次数太多导致主机被block的问题处理

参数max_connect_errorsMySQL有参数max_connect_errors,当一个主机尝试登录MySQL,失败的次数超过了max_connect_errors,则这个主机将无法登录到...

MySQL运维实战(3.3) 管理数据库(database)

数据库使用create database语句创建数据库。创建数据库的账号需要有create权限。创建数据库用户拥有create权限才能创建数据库。-- 例子:创建dba用户,拥有创建数据库名...

发表评论    

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