索引分类
1 | create table s1( |
普通索引
index :加速查找
1 | -在创建表后在创建 |
唯一索引
主键索引:primary key :加速查找+约束(不为空且唯一)
唯一索引:unique:加速查找+约束 (唯一)
1 | create unique age on s1(age);添加唯一索引 |
联合索引
-primary key(id,name):联合主键索引
-unique(id,name):联合唯一索引
-index(id,name):联合普通索引
1 | create index name on s1(id,name); #添加普通联合索引 |
全文索引
fulltext :用于搜索很长一篇文章的时候,效果最好。
空间索引
spatial :了解就好,几乎不用
使用索引
覆盖索引
1 | select * from s1 where id=123; |
联合索引
1 | create index ne on s1(name,email);#组合索引 |
最左前缀匹配
1 | create index ne on s1(name,email);#组合索引 |
MySQL 8.0.13版本引入了索引跳跃扫描(Index Skip Scan)优化,需要最左侧区分度高,及限制
- 表T至少有一个联合索引,但是对于联合索引(A,B,C,D)来说,A和D可以是空的,但B和C必须是非空的。
- 查询必须只能依赖一张表,不能多表join
- 查询中不能使用GROUP BY或DISTINCT语句
- 查询的字段必须是索引中的列
会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配
1 | 比如a = 1 and b = 2 and c > 3 and d = 4 |
使用like 'x%'
会走索引
尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),
表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、
性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,
这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录
索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’
所以语句应该写成create_time = unix_timestamp(’2014-05-29’);