单个索引
1.1 BTREEand HASH索引:使用=,<=>,IN,IS NULL,IS NOT NULL操作
1.2 BTREE索引: >,=,<=,BETWENN,!=, <>, LIKE(不是以通配符开头)
1.3 所有索引,多个区间条件可以用OR或者AND连接
例:
SELECT * FROM t1 WHERE key_col > 1 AND key_col < 10;
SELECT * FROM t1 WHERE key_col = 1 OR key_col IN (15,18,20);
SELECT * FROM t1 WHERE key_col LIKE 'ab%' or key_col BETWEEN 'bar' AND 'foo';
一些非常数值转换成常数值在优化器的常数传播时期(constant propagation phase)
Mysql会尽可能将区间查询条件中的索引提取出来。在这个提取阶段会做如下几件事:
1 那些无法构成区间条件的条件将会被删除.
2 区间重叠的条件将会合并
3 空范围的将会被删除
例:
SELECT * FROM t1 WHERE(key1是索引,nonkey不是索引)
(key1 < 'abc' AND (key1 LIKE 'abcd%' OR key1 LIKE '%b')) OR
(key1 < 'bar' AND nonkey = 4) OR
(key1 < 'uux' AND key1 > 'z');
提取过程(对于index key1)如下:
删除nonkey = 4 和 key1 LIKE '%b',因为这两个条件无法使用区间扫描,正确的方式是将这两个替换成TRUE,这样我们就不会漏掉任何一条匹配的行了
(key1 < 'abc' AND (key1 LIKE 'abcd%' OR TRUE)) OR
(key1 < 'bar' AND TRUE) OR
(key1 < 'uux' AND key1 > 'z');
条件替换(可以确定为TRUE OR FALSE的值)
(key1 LIKE 'abcde%' OR TRUE) is always true
(key1 < 'uux' AND key1 > 'z') is always false
替换之后
(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
删除不必要的 TRUE 和 FALSE
(key1 < 'abc') OR (key1 < 'bar')
合并重叠部分则变成了
(key1 < 'bar')
通常情况下,范围扫描的限制性是小于WHERE。Mysql在检查过滤行时会优先满足范围条件而不是所有的WHERE条件