了解B树和哈希数据结构有助于预测查询在这些使用不一样索引数据结构的存储引擎上的执行状况,特别是对于MEMORY存储引擎,它是容许您选择B树或哈希做为索引的存储引擎。mysql
B树索引能够在使用表达式中使用的对列的比较 =, >, >=, <, <=,或BETWEEN关键字。若是使用LIKE 或to LIKE且是一个不以通配符开头的常量字符串,则索引也可用于比较 。算法
1.例如,如下SELECT语句将使用索引:sql
SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%'; SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';
在第一个语句中 'Patrick' <= key_col < 'Patricl',在第二个语句中'Pat' <= key_col < 'Pau'数据结构
2.如下SELECT语句不使用索引:函数
SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%'; SELECT * FROM tbl_name WHERE key_col LIKE other_col;
在第一个语句中,LIKE 值以通配符开头。在第二个语句中,该LIKE值不是常量。优化
若是使用了像'%string%'且长度超过三个字符的字符串查询,那么MySQL将使用Turbo Boyer-Moore算法初始化这个模型,用这个模型来匹配速度会更快.spa
不跨越子句中的全部AND级别的 任何索引 WHERE不用于优化查询。换句话说,为了可以使用索引,必须在每一个AND组中使用索引的前缀 。code
3.如下WHERE子句使用索引:索引
WHERE index_part1=1 AND index_part2=2 AND other_column=3 /* index = 1 OR index = 2 */ WHERE index=1 OR A=10 AND index=2 /* optimized like "index_part1='hello'" */ WHERE index_part1='hello' AND index_part3=5 /* Can use index on index1 but not on index2 or index3 */ WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
4.这些WHERE子句 不使用索引:字符串
/* index_part1 is not used */ WHERE index_part2=1 AND index_part3=2 /* Index is not used in both parts of the WHERE clause */ WHERE index=1 OR A=10 /* No index spans all rows */ WHERE index_part1=1 OR index_part2=10
有时MySQL不使用索引,即便有索引也是如此。发生这种状况的一种缘由是,优化器估计使用索引将须要MySQL访问表中很是大比例的行。(在这种状况下,表扫描可能会快得多,由于它须要的搜索次数较少。)可是,若是这样的查询:例如LIMIT只用于检索某些行,那么MySQL不管如何都会使用索引,由于它能够更快地找到在结果中返回几行。
散列索引与刚才讨论的特征有些不一样:
相同点: 像常规的=运算符同样,两个值进行比较,结果是0(不等于)或1(相等),换句话说:’A'<=>’B'得0和’a'<=>’a‘得1,都是值的比较。不一样点: NULL的值是没有任何意义的。因此=号运算符不能把NULL做为有效的结果。因此:请使用<=>,'a' <=> NULL 得0 NULL<=> NULL 得出 1。和=运算符正相反,=号运算符规则是 'a'=NULL 结果是NULL 甚至NULL = NULL 结果也是NULL。顺便说一句,mysql上几乎全部的操做符和函数都是这样工做的,由于和NULL比较基本上都没有意义。用处当两个操做数中可能含有NULL时,你须要一个一致的语句,此时就能够用<=>.