【最佳实践】MySQL 索引性能优化


环境:MySQL 5.7.22 InnoDB

只为用于搜索、排序或分组的列创建索引

我们只为出现在 WHERE 子句中的列、连接子句中的连接列,或者出现在 ORDER BY 或 GROUP BY 子句中的列创建索引即可。

索引用于搜索

对于某个查询来说,最简单粗暴的执行方案就是扫描表中的所有记录,判断每一条记录是否符合搜索条件。如果符合,就将其发送到客户端,否则就跳过该记录。这种执行方案也称为全表扫描。
对于使用 InnoDB 存储引擎的表来说,全表扫描意味着从聚簇索引第一个叶子节点的第一条记录开始,沿着记录所在的单向链表向后扫描,直到最后一个叶子节点的最后一条记录。全表扫描是一种万能的执行方案,所有的查询都可以使用这种方案来执行。
我们可以利用 B+ 树查找索引列值等于某个值的记录,这样可以明显减少需要扫描的记录数量。由于 B+树叶子节点中的记录是按照索引列值由小到大的顺序排序的,所以只扫描某个区间或者某些区间中的记录也可以明显减少需要扫描的记录数量。比如下面这个查询语句:
SELECT * FROM single_table WHERE id >= 2 AND id = 100;
这个语句其实是想查找 id 值在[2,100] 区间中的所有聚簇索引记录。我们可以通过聚簇索引对应的 B+树快速地定位到过值为 2 的那条聚簇案引记录,然后沿着记录所在的单向链表向后扫描,直到某条聚簇索引记录的 id 值不在[2,100]区间中为止(即 id 值不再符合 d<=100 条件)。
与扫描全部的聚簇索引记录相比,扫描 id 值在(2,100]区间中的记录己经很大程度地減少了需要扫描的记录数量,所以提升了查询效率。简便起见,我们把这个例子中待扫描记录的id 值所在的区间称为扫描区间,把形成这个扫描区间的搜索条件(也就是 id>=2 AND id <100) 称为形成这个扫描区间的边界条件
在使用某个索引执行查询时,关键的问题就是通过搜索条件找出合适的扫描区间,然后再到对应的 B+中扫描崇引列值在这些扫描区闻的记录。对于每个扫描区间来说,仅需要通过 B+ 树定位到该扫描区间中的第一条记录,然后就可以沿着记录所在的单向链表向后扫描,直到某条记录不符合形成该扫描区间的边界条件为止。其实对于B+树索引来说,只要索引列常数使用=、[[<=>]]、IN、 NOT IN、 IS NULL、 IS NOT NULL、>、<、>=、 <=、BETWEEN、!=(也可以写成<>)或者LIKE 操作符连接起来,就可以产生所谓的扫描区闻。不过有下面几点需要注意:

  • IN操作符的语义与若干个等值匹配操作符(=)之间用 OR 连接起来的语义是一样的,都会产生多个单点扫描区间。比如下面这两个语句的语义效果是一样的:
    SELECT * FROM single_table WHERE key2 IN (1438, 6328)SELECT 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值