- 列要独立:where查询语句中,索引部分最好放在等式左边,等式右边放置比较值,而且左边最好都是索引,Mysql并不能分辨某些情况,例如
WHERE A + 1 = 5;
就无法用到A的索引 - explain 命令获取 select 语句的执行计划
前缀索引
- 对于TEXT、BLOB类型或者很长的varchar类型,必须要用前缀索引
- 前缀取多少合适呢?取多了会导致索引过长,取少了导致结果重叠,选择区分性较差,前缀索引取多少合适呢?可以先尝试着取,然后查看结果与真实结果的吻合程度,两种方式如图
- 创建前缀索引的语句例子
ALTER TABLE sakila.city_demo ADD KEY (city(7));
- 前缀索引无法做ORDER BY和GROUP BY操作
多列索引
- 为每个列创建单独的索引,这是一种策略,但是在大部分情况下并不能很好的提高mysql的查询性能,在msyql中使用了一种叫做索引合并的策略。例如如果在A,B列上分别创建了两个索引,那么类似于条件A and B会被转换成两个查询语句,并将结果做intersection(交集)运算。
- 但是如果想做相交查询,最好建立多个列的单一索引
- 对于or操作,多个索引会耗费大量CPU和内存资源在算法的缓存、排序和合并操作上
合适的索引列顺序(适合B树等顺序结构)
- 当不需要考虑排序和分组时,将选择性最高的列(区别度最大的列)放在前面
聚簇索引
- 聚簇索引描述的是一种数据存储方式,表示数据行和相邻的键值紧紧储存在一起。将数据存储与索引放到了一块,找到索引也就找到了数据
上面的B+树就是聚簇索引,当找到一个叶子节点的索引时,就找到了对应的储存块 - 聚簇索引的优点:
- 由于索引和数据存放在一起,当通过索引查找时,对应的储存块也被加载到了内存中,避免了额外的IO操作
- 访问更快
- 使用索引覆盖扫描的时候可以直接使用叶节点的主键值
- 缺点:
- 提高了IO密集型应用性能,但是如果数据可以直接放在内存中,那么提升就很微小了
- 插入速度严重依赖于插入顺序。按照主键的顺序插入是加载数据到InnoDB表中速度最快的方式。但如果不是按照主键顺序加载数据,那么在加载完成后最好使用OPTIMIZE TABLE命令重新组织一下表
- 更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的行移动到新的位置。
- 基于聚簇索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂(page split)”的问题。当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次页分裂操作。页分裂会导致表占用更多的磁盘空间。
- 聚簇索引可能导致全表扫描变慢,尤其是行比较稀疏,或者由于页分裂导致数据存储不连续的时候
- 二级索引:叶子节点中存储主键值,每次查找数据时,根据索引找到叶子节点中的主键值,根据主键值再到聚簇索引中得到完整的一行记录。
InnoDB和MYISAM中的索引
- InnoDB支持聚簇索引,而MYISAM不支持