然后我使用这条sql语句 EXPLAIN SELECT first_name,age from user where first_name='张' and age >0,在这条sql语句中我查询两个不同索引中的列查询结果如下所示;
在这条sql语句中我使用了两个索引idx_fk_name和idx_fk_age,查询的列和查询条件都是在这两个索引中,测试的结果为using where(需要回表查询所需要的数据)。接下来我们使用这个sql语句 EXPLAIN SELECT last_name FROM user where first_name = '张',使用结果如下图所示:
索引匹配
如果我们书写的sql语句符合索引匹配原则,那么我们就可以不进行索引的全部数据扫描,结果就是我们的查询效率又变高了。那么索引匹配原则是啥?我就简略的总结一下吧。
全值匹配全值匹配就是查询条件和索引中的所有列进行匹配。如我上面创建的idx_fx_name索引。select * from user where first_name='张' 和 last_name = '三' 这条sql语句就是全值匹配。注意如果写成last_name='三' and first_name='张'也是全值匹配
最左匹配我把书中匹配最左前缀和匹配列前缀都划分为最左匹配,因为我觉得它都是从最左边开始匹配的,好像网上也是这么说的。
最左前缀就是你写的条件查询语句针对于某个索引来说它符合从左边一个一个进行匹配的方式(经过实测条件语句的顺序不影响最左匹配的原则),再拿我的idx_fx_name索引来举个例子。如select * from user where last_name = '三'和 select * from user where first_name = '张' 这两个sql语句查询索引的方式都不一样,前者是扫描索引所有数据,第二个就只扫描了索引的部分数据。测试结果如下所示:
匹配范围值
在符合最左匹配的基础上可以使用范围进行查询。
精确匹配加范围匹配在符合最左匹配的基础上最后一个查询条件可以记性范围查询。
索引创建优化 前缀索引和索引选择性
我们先说说索引的选择性吧。索引的选择性是指不重复的索引值(也称为基数,cardinality)和数据表的记录总数(#T)的比值,范围从1/#T到1之间❸。这句话通俗的理解就是你选择作为索引(当然是只能选择某个字段,字段的全部或者部分)的数据在表中这个字段列中重复率越低越好,因为这样可以过滤更多的数据行。前缀索引就是可以拿某个字段的前缀作为索引之所以把前缀所以和索引选择性放到一起说是为了解决当我们选择一个特别长的字段作为索引时首先会很浪费空间其次是查询的时候速度肯定会比较慢。
那么我们怎么计算索引选择性的高低呢?这个有方法的,方法就是通过关键字DISTINCT 和 Count来计算索引的选择性。如我计算first_name的选择性高低可以这样计算:
select count(DISTINCT first_name) / count(1) as a1 from user;
如果我要计算以first_name前三个字符作为索引的话计算选择性可以这样写:
select count(DISTINCT LEFT(first_name,3)) / count(1) as a1 from user;
通过不断的修改所包含的前缀的大小我们就能找到选择性高的索引。
选择合适的索引序列其实选择合适的索引序列我觉得根据实际情况来做分析。不过一般来说我们都把选择性高的放在前面,其他的就是要根据where子句中的排序、分组和范围条件等其他因素来选择索引的序列
不创建冗余和重复的索引这里有两个问题摆在我们的面前什么是冗余的索引?什么是重复索引?
重复索引:具有相同列的索引就是重复索引。如(A,B)和(B,A)就是重复索引。
冗余索引:一个索引的子集就是冗余索引。如(A,B,C) 和(A,B) (B,C)就是冗余索引。
从一般情况来说就是尽量不创建重复索引和冗余索引,但是在特殊的情况下我们可以创建冗余索引。
总结
以上就是我学习《高性能mysql》书籍的总结。如果有什么问题请大家及时反馈给我毕竟互相交流才能促进学习。
借鉴书籍或博客❶
❷《高性能mysql》第五章第三节
❸《高性能msql》第五章第三节第二小节