原文参考
一、前言
在MySQL中进行SQL优化的时候,经常会在一些情况下,对MySQL能否利用索引有一些迷惑。
譬如:
1.MySQL 在遇到范围查询条件的时候就停止匹配了,那么到底是哪些范围条件? 2.MySQL 在LIKE进行模糊匹配的时候又是如何利用索引的呢? 3.MySQL 到底在怎么样的情况下能够利用索引进行排序? 4.今天,我将会用一个模型,把这些问题都一一解答,让你对MySQL索引的使用不再畏惧
二、补充知识
key_len
EXPLAIN执行计划中有一列 key_len
用于表示本次查询中,所选择的索引长度有多少字节,通常我们可借此判断联合索引有多少列被选择了。
在这里 key_len 大小的计算规则是:
- 一般地,
key_len
等于索引列类型字节长度,例如int类型为4bytes
,bigint为8bytes
; - 如果是字符串类型,还需要同时考虑字符集因素,例如:CHAR(30) UTF8则key_len至少是90
bytes
; - 若该列类型定义时允许NULL,其
key_len
还需要再加 1bytes
; - 若该列类型为变长类型,例如
VARCHAR
(TEXT\BLOB不允许整列创建索引,如果创建部分索引也被视为动态列类型),其key_len
还需要再加 2bytes
;
三、哪些条件能用到索引
首先非常感谢登博,给了我一个很好的启发,我通过他的文章,然后结合自己的理解,制作出了这幅图
乍一看,是不是很晕,不急,我们慢慢来看
图中一共分了三个部分:
1.Index Key :MySQL是用来确定扫描的数据范围,实际就是可以利用到的MySQL索引部分,体现在Key Length。 2.Index Filter:MySQL用来确定哪些数据是可以用索引去过滤,在启用ICP后,可以用上索引的部分。 3.Table Filter:MySQL无法用索引过滤,回表取回行数据后,到server层进行数据过滤。 我们细细展开。
Index Key
Index Key是用来确定MySQL的一个扫描范围,分为上边界和下边界。
MySQL利用=、>=、> 来确定下边界(first key),利用最左原则,首先判断第一个索引键值在where条件中是否存在,如果存在,则判断比较符号,如果为(=,>=)中的一种,加入下边界的界定,然后继续判断下一个索引键,如果存在且是(>),则将该键值加入到下边界的界定,停止匹配下一个索引键;如果不存在,直接停止下边界匹配。
exp: idx_c1_c2_c3(c1,c2,c3) where c1>=1 and c2>2 and c3=1 –> first key (c1,c2) –> c1为 ‘>=’ ,加入下边界界定,继续匹配下一个 –> c2 为 ‘>’,加入下边界界定,停止匹配
上边界(last key)和下边界(first key)类似,首先判断是否是否是(=,<=)中的一种,如果是,加入界定,继续下一个索引键值匹配,如果是(<),加入界定,停止匹配。
exp: idx_c1_c2_c3(c1,c2,c3) where c1<=1 and c2=2 and c3<3 –> first key (c1,c2,c3) –> c1为 ‘<=’,加入上边界界定,继续匹配下一个 –> c2为 ‘=’加入上边界界定,继续匹配下一个 –> c3 为 ‘<‘,加入上边界界定,停止匹配
注:这里简单的记忆是,如果比较符号中包含’=’号,’>=’也是包含’=’,那么该索引键是可以被利用的,可以继续匹配后面的索引键值; 如果不存在’=’,也就是’>’,’<‘,这两个,后面的索引键值就无法匹配了。 同时,上下边界是不可以混用的,哪个边界能利用索引的的键值多,就是最终能够利用索引键值的个数。