索引
索引的常见类型
哈希表
哈希表是一种以键 - 值(key-value)存储数据的结构。
这种结构适用于只有等值查询的场景。
有序数组
有序数组在等值查询和范围查询场景中的性能都非常优秀。但是由于插入操作需要移动数组,所以有序数组索引只适用于静态存储引擎。
搜索树
搜索树的查询复杂度是O(logN)、更新的时间复杂度也是O(logN)。
MyISAM和InnoDB存储引擎的表默认创建的是树索引
哈希表与搜索树
哈希索引有一些重要特征需要在使用的时候特别注意
只用于使用=或<=>操作符的等式比较
优化器不能使用哈希索引来加速ORDER BY操作
MySQL不能确定在两个值之间大约有多少行。如果将一个MyISAM表改为哈希索引的MEMORY表,会影响一些查询的执行效率。
只能使用整个关键字来搜索一行
对于树索引,当使用>、<、>=、<=、BETWEEN、!=或者<>,或者LIKE 'pattern'(其中'pattern'不以通配符开始)操作符时,都可以使用相关列上的索引。
了解了BTREE索引和HASH索引不同后,当使用MEMORY表时,如果是默认创建的HASH索引,就要注意SQL语句的编写,确保可以使用上索引,如果一定要使用范围查询,那么在创建索引时,就应该选择创建成BTREE索引。
索引的设计原则
最适合索引的列是出现在WHERE子句中的列,或连接子句中指定的列
索引的列的基数越大,值越分散,索引的效果越好
如果对字符串进行索引,应该指定一个前缀长度。
较小的索引涉及的磁盘IO较少,较短的值比较起来更快。更为重要的是,对于较短的键值,索引高速缓存中的块能够容纳更多的键值,因此,MySQL也可以在内存中容纳更多的值。这样就增加了找到行而不用读取索引中较多块的可能性。
不要过度索引,每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能。
对于InnoDB存储引擎的表,尽量自己指定主键。InnoDB表的普通索引会保存主键的键值,所以主键要尽可能选择较短的数据类型,可以有效地减少索引的磁盘占用,提高索引的缓存效果。
索引的使用
主键索引和普通索引的不同
主键索引的叶子解点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引。
非主键索引(普通索引)的叶子解点内容是主键的值。因此,主键长度越小,普通索引的叶子解点就越小,普通索引占用的空间也就越小。在InnoDB里,非主键索引也被称为二级索引。
普通索引查询方式,需要先查询出主键,再到主键索引树查询。这个过程称为回表。也就是说,基于非主键索引的查询需要多扫描一棵索引树。
覆盖索引
如果我们所需要查询的值已经在索引树上,就不需要回表。由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
最左前缀原则
B+树这种索引结构,可以利用索引的“最左前缀”来定位记录。即使用联合索引时,可以只使用左侧的索引字段。
存在索引但是不能使用索引的经典场景
以%开头的LIKE查询不能够利用B-Tree索引
数据类型出现隐式转换的时候也不会使用索引,特别是当列类型是字符串。
复合索引的情况下,假如查询条件不包含索引最左边部分,即不满足最左原则Leftmost,是不会使用复合索引的
如果MySQL估计使用索引比全表扫描更慢,则不使用索引
用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到
Last updated