写在前面:
索引的三个优点:
- 索引大大减少了服务器需要扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 索引可以将随机 I/O 变为顺序 I/O
- 索引一般分为:
主键索引:不能为空 不能重复
普通索引
create index 索引名称 on 表名(列名,)
drop index 索引名称 on 表名
唯一索引:不能重复
create unique index 索引名称 on 表名(列名)
drop unique index 索引名称 on 表名
联合(组合)索引
create unique index 索引名称 on 表名(列名,列名)
drop unique index 索引名称 on 表名
如果有组合索引,注意最左前缀匹配,从最左边开始匹配
注意索引合并只是配合两个单独的索引而已。
组合索引效率 > 索引合并效率
高性能索引策略
-
独立的列
指的是索引列不能是表达式的一部分,也不能是函数的参数
不好的索引
select actor_id from sakila.actor where actor_id+1 = 5
我们应该简化 where 条件,始终将索引列单独放在比较符号的一侧。
不好的又一个示例:
select ... where to_days(current_date) - to_days(date_col) <= 10
-
前缀索引和索引选择性
有时候需要索引很长的字符列,一个策略是模拟哈希索引,还有一个策略是:通常可以索引开始的部分字符,但这会降低索引的选择性。
索引的选择性:不重复的索引值和数据表的记录总数的比值,索引的选择性越高查询效率越高。唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。
对于 BLOB,TEXT 或很长的 varchar 类型列,必须使用前缀索引。
缺点:MySQL 无法使用前缀索引做 order by 和 group by,也无法使用前缀索引做覆盖扫描。
当然也可以创造后缀索引,只需将字符串反向存储即可。 -
多列索引
通常“把 where 条件里面的列都建上索引”这样模糊的建议是错误的,在多个列上建立独立的单列索引大部分情况并不能提高 MySQL 的查询性能。有时可以优化索引列的顺序。 -
选择合适的索引列顺序
-
散列值少的不适合建索引
如性别 -
聚簇索引
这是一种数据存储方式。表数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。
非聚簇索引
表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。 -
覆盖索引
在索引文件中直接找到数据,只是一个名词,不是真实的索引 -
使用索引扫描来做排序
-
压缩(前缀压缩)索引
MyISAM 使用前缀压缩来减少索引的大小。 -
冗余和重复索引
例如在 primary key 列上又创建 unique ,通常没有必要。
还有创建了索引(A,B),再创建(A)就是冗余索引,因为它是 (A,B)的前缀索引。但(B,A),(B)就不是了。 -
未使用的索引
有一些索引永远不会被使用。建议删除。
以下几种情况不会命中索引:
like 使用函数, or,类型不一致 != > order by
or 可能会出现没法走索引,但如果where 索引1=xxx or field=xxx and 索引2=xxx
它就会走索引
用 order by 的时候,注意取 order by 字段,否则不会走索引。一般主键都有特殊性,对于 != < > 会走索引。
网友评论