介绍
索引用来快速定位一些查询的行值。如果不使用索引的话,MySQL必须从整张表的第一行顺序读取所有行来查找查询相关的行。如果数据表越大,那么查询开销越大。如果查询的列上有索引,那么MySQL可以通过使用索引来快速定位到数据行而不用顺序读取整张表。所以使用索引来查询行记录比顺序读取每一行数据要快很多。
MySQL中大部分索引都是使用B-tree数据结构来存储,比如:主键、唯一索引、普通索引和全文索引。但是空间数据类型使用R-tree数据结构来存储索引。MEMORY存储引擎的表不仅支持Tree索引,而且还是支持哈希索引。InnoDB使用反向列表来存储全文索引。
MySQL使用索引的操作
- 匹配Where 子句来快速查找行
- 通过比较选择最佳索引。
如果操作中有多个索引可以使用,那么MySQL通常使用最小数据行的那个索引
- 如果表有多列索引(组合索引),那么MySQL优化器使用最左前缀匹配原则来查找行。
例如:如果在一张表上有一个三列索引(col1,col2,col3),那么在查询条件为(col1)、(col1,col2)和(col1, col2, col3)的查询语句中会使用这个三列索引。
- 使用索引来优化join。
MySQL会使用索引来优化链接查询,前提条件是在on条件语句中的列有相同的数据类型和数据长度。特别说明一点的是:VARCHAR和CHAR被认为是相同类型的,但是前提是他们有相同的数据长度。例如:VARCHAR(10)和CHAR(10)是相同的数据类型,但是VARCHAR(10)和CHAR(15)不是相同的数据类型。
对于非二进制字符串列的比较,两个列应该使用相同的字符编码。例如:一个使用utf8的列和一个使用Latin1的列是无法使用索引的。
比较不同的数据类型的列,如果两个列无法通过MySQL自动数据类型转换那么就无法使用索引。例如:给一个数字的1和一个字符串列比较,字符串列的值可能是'1', ' 1', '0001', 或'01.e1'。在这个规则下,MySQL不会使用字符串列的索引。
- 使用索引在指定的索引列上查找MIN()和MAX()。
- 排序或分组
- 覆盖索引。通过索引来查找所有的数据行及列数据而不用再去表中查询。
补充
以下两种情况索引就显的没有那么重要了:
- 小表:数据行小或表文件比较小
- 大表但是需要查询很多行。
当一个查询需要访问大多数行,顺序读取会比通过索引定位读取更快。尽管并不是所有的行都是这个查询需要的,但是顺序读取能够减小磁盘定位(磁盘寻址时间=寻道时间(seek time)+旋转延迟时间(rorational latency)+数据传输时间(transfer time))。