index
索引用于疾速查找具备特定列值的行,如果没有索引,mysql必须从第一行开始,扫描全表找到对应的行。表越大,破费越多。如果表中有相干的索引,mysql能够疾速确定要在数据文件中查找的地位。大多数mysql索引(primary key,unique,index和fulltext)存储在B-trees。空间数据类型的索引应用R-trees;MEMORY表还反对hash indexes;InnoDB对fulltext应用倒排表。
MySQL应用索引进行以下操作:
- 通过where条件疾速查问。
- 最优匹配。如果能够在多个索引之间进行抉择,则MySQL通常会应用查找最小行数的索引。
- 如果表具备多列索引,那么优化器能够应用索引的任何最左前缀来查找行。举例来说,如果你有一个三列的索引 (col1, col2, col3),你能够索引的搜寻有(col1), (col1, col2)以及(col1, col2, col3)。
- 执行联接时从其余表中检索行。如果申明雷同的类型和大小,MySQL能够更无效地在列上应用索引。在这种状况下, VARCHAR与 CHAR被认为是雷同的,如果它们被申明为雷同的大小。例如, VARCHAR(10)和 CHAR(10)是雷同的大小,然而 VARCHAR(10)和 CHAR(15)不是。
对于非二进制字符串列之间的比拟,两个列应应用雷同的字符集,不同的字符集将导致索引生效。例如,将utf8列与latin1列进行比拟会排除应用索引。
如果不能不通过转换间接比拟值,则比拟不同的列(例如,将字符串列与工夫或数字列进行比拟)可能会阻止应用索引。对于给定的值,如数值列的值为1,它可能比拟等于在字符串列,例如任何数量的值 '1',' 1', '00001',或'01.e1',导致索引生效。 - 在索引列应用MIN()或 MAX()。mysql预处理器将进行优化,预处理器会查看您是否正在索引呈现的所有要害局部上应用。在这种状况下,MySQL为每个表达式执行一次键查找,并将其替换为常量,所有表达式都用常量替换实现后,查问将立刻返回。
- 排序或分组查问(order by, group by)应用最左匹配索引(order by key1, key2);如果倒序排序(order by key1, key2 desc),将按相同程序应用索引key。
- 某些状况下,mysql会间接从索引中获取数据,而不必查问表;例如:只查问索引列数据。留神:当开启列长事务时,可能导致该优化生效,回表查问。
- 当全表扫描快于走索引查问时,mysql也不会走索引。
covering index
查问的所有列都蕴含在索引中时,mysql不会扫描表(即不会回表查问),这种状况mysql定义为covering index;InnoDb引擎下,开启事务时,将不会应用这种优化查问。
参考资料
8.5.2 Optimizing InnoDB Transaction Management