MySQL索引自优化算法

15次阅读
没有评论

共计 1445 个字符,预计需要花费 4 分钟才能阅读完成。

InnoDB 架构图:
InnoDB 架构图

查看优化器算法开关:select @@optimizer_switch;

修改,例如:set global optimizer_switch='batched_key_access=on';,退出客户端,重新进入客户端查看修改结果。

设置方法也可以使用优化器提示 Hints 的形式,或者设置 my.cnf 配置文件。

索引自优化

AHI

Adaptive Hash Index,即自适应哈希索引,作用是自动评估热内存索引 page,生成 Hash 索引表,帮助 InnoDB 快速读取索引页,加快索引读取的速度,相当于索引的索引。

Change Buffer

比如 insert、update、delete 数据,对于聚簇索引会立即更新,而对于辅助索引不是实时更新的。

在 InnoDB 内存结构中,加入了 Insert Buffer,现在版本叫 Change Buffer。Change Buffer 功能是临时缓冲辅助索引需要的数据更新。当我们需要査询新 insert 的数据,会在内存中进行 merge 合并操作,此时辅助索引就是最新的。

优化器算法

ICP

Index Condition Pushdown,即索引下推,作用是解决联合索引只能部分应用的情况。为了减少没必要的数据页被扫描,将不走索引的条件,在 engine 层取数据之前先做二次过滤,一些无关数据就会被提前过滤掉。

例如,有一个索引 index(a,b,c),查询语句:select * from t where a= and c=,在 server 层先做 a 列过滤条件的索引优化,在将 c 列的过滤下推到 engine 层先做过滤,再加载数据页。

MRR

Multi-Range Read,是优化器将随机磁盘 IO 转化为顺序磁盘 IO 以降低查询过程中 IO 开销的一种手段,是一种回表优化。

回表是指先走二级索引,找到对应的主键值,再根据主键值再到聚集索引当中,拿到一行行的数据。由于二级索引上引用的主键值不一定是有序的,因此有可能造成大量的随机 IO,如果回表前把主键值给排下序,那么在回表时就可以用顺序 IO 取代原本的随机 IO。

具体可参考:https://mariadb.com/kb/en/multi-range-read-optimization/

SNLJ

Index Nested-Loop Join,INLJ 算法,即嵌套循环连接,常用于连接小表或是一个表中数据量不大的子集。具体实现方式是先遍历外表,对于每一行,再遍历内表,找到符合连接条件的行,返回结果。

Simple Nested-Loop Join,即 SNLJ 算法。具体实现方式是驱动表全表扫描取出所有字段,逐行匹配被驱动表,而被驱动表未使用到索引,每次匹配页都进行一次全表扫描。

BNL

Block Nested-Loop Join,即块嵌套循环连接。该算法使用了 join buffer 作为优化,其中由参数 join_buffer_size 设定 join_buffer 大小,默认值是 256K。

在 A 表和 B 表关联条件匹配时,不再一次一次进行循环,而是采用一次性将驱动表的关联值和非驱动表匹配. 一次性返回结果。BNLJ 算法主要优化了 CPU 消耗,减少了 IO 次数。

BKA

Batched Key Access,主要是用来优化非驱动表关联列有辅助索引,相当于 BNL+MRR 的功能。要启动 KBA 算法优化,先设置:set global optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on';,退出客户端,重新进入客户端查看修改结果。

正文完
post-qrcode
 0
三毛
版权声明:本站原创文章,由 三毛 于2024-02-22发表,共计1445字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)