本文主要介绍了MySQL的复合索引的概要,并对索引进行了一些优化。一些表结构已经有许多索引。如果继续添加索引,必然会影响插入数据的性能。有需要的朋友可以参考一下。
: 目录
1.背景2。理解复合指数3。最左侧匹配原则4。场序5的影响。单个字段可以触发索引吗?7.复合指数能代替单一指数吗?
1.背景
最近频繁出现的慢SQL导致系统性能问题,我决定对索引做一些优化。一些表结构已经有许多索引。如果继续添加索引,必然会影响插入数据的性能。那么,有没有可能用组合指数来达到目的呢?让我们来看看这篇文章。
2.了解复合指数
如果在where条件中使用了多个字段,并且需要对多个字段进行索引,那么可以考虑复合索引(组合索引)。比如查询地址,需要输入省或市,那么在省或市建立索引,在数据量较大的情况下会明显提高查询速度。
组合索引有啥优势呢?
减少查询开销:
建立复合指数(c1,c2,c3)实际上相当于建立三个指数(C1),(C1,C2)和(C1,C2,C3)。对于大型表,开销可以大大降低。覆盖索引:
MySQL可以通过遍历索引直接获取数据,无需返回表,减少了大量的随机io操作。效率高:
索引中的列越多,通过索引过滤的数据就越少,从而提高了查询效率。缺点:
索引字段越多,创建的索引越多,每个索引都会增加磁盘空间的开销;
索引越多,查询效率就越高,但是需要更新的索引的添加、删除、修改都会产生高效的影响。
使用复合索引的建议:单个表最好不要超过1个复合索引,单个复合索引最好不要超过3个字段。一旦超过,就要考虑必要性,是否有其他替代方案。
3.最左匹配原则
复合索引遵循最左侧匹配原则。顾名思义,在复合索引中,最左边的字段首先匹配。因此,创建复合索引时,where子句中最常用的字段放在复合索引的最左侧。
二级索引由B树实现。虽然可以指定多个列,但是每个列的比较优先级不同,写在前面的优先级更高。一旦有遗漏,就无法在B树上继续搜索(用补全等措施解决的除外),所以是基于最左边的连续匹配。既然是在B树上搜索,条件的比较自然需要精确匹配(即=和 in )。
where子句中使用了两个字段c1和c2,那么在创建索引时,这两个字段的顺序应该是(c1,c2)还是(c2,c1)?
正确的做法是:
把重复值最少的放前面。例如,如果95%的值没有重复,则考虑将它们放在第一位。4.场序的影响
复合索引遵循最左匹配原则,那么where查询条件中的字段是否也需要按照索引的顺序书写?
比如复合索引为(c1,c2,c3),那么下面两个查询条件会影响索引吗?
select * from t_user其中c1=1,C2=4;
select * from t_user其中c2=4,C1=1;
看一篇文章中第一条SQL语句效率更高可信吗?两种查询方式的条件是一样的,结果应该是一样的。正常情况下,Mysql会让它们取相同的索引。
通过Mysql的查询优化器explain分析上面两条语句,会发现执行计划完全一样。也就是说,SQL语句中字段的顺序不需要和复合索引字段的顺序一致,查询优化器会自动调整顺序。
如果提到效率的影响,那就是查询优化器的修正顺序的影响,几乎可以忽略不计。
5.单个字段可以触发索引吗?
对于复合索引为(c1,c2,c3)的三个索引,相当于(c1),(C1,C2),(C1,C2,C3),如果查询条件中只有C1,显然会取该索引。
但如果where条件如下呢:
从t_user其中C2=4;
上面的语句会索引吗?给这些情况打分来说明。
执行explan查询c1为条件的SQL语句:
解释select * from t_user其中C1=1;
上面语句的索引类型是:ref。ref类型表示Mysql会根据特定的算法快速找到符合条件的索引,而不是扫描判断索引中的每一个数据。为了快速找到数据,这种类型的索引需要满足一定的数据结构。
执行explan查询c2为条件的SQL语句:
解释select c2 from t_user其中C2=4;
上述语句的索引类型为:index。索引类型表示Mysql会扫描整个索引,只要是索引或者索引的一部分,Mysql都有可能扫描。因为这种方法是逐数据搜索,所以性能不高。
在本例中,对要查询的字段有一定的要求。where中的条件是c2,select中要查询的字段只能是c2,所以会使用索引类型。
如果将c2换成*或其他字段:
解释select * from t_user其中C2=4;
上面的语句会发现,它会扫描整个表,而不是索引index。这也从侧面解释了为什么Mysql要讲最左匹配原则。
所以结论是:如果单个字段是综合指数的第一个字段,指数会正常走;如果单个字段是复合索引的其他字段,并且只有该字段出现在select后,索引类型将取index;在其他情况下,采用全表扫描。
7.复合指数能代替单一指数吗?
单一索引:
(c1),
复合索引:
(c1,c2).
当使用c1作为查询条件时,单索引和复合索引的查询速度几乎相同,甚至略快于复合索引。
如果只使用复合聚集索引的非起始列(c2)作为查询条件,复合索引将不起作用。
对于一个表,如果有复合索引(c1,c2),就不需要构建单个索引(c1)。
如果单个索引(c1)已经存在,由于查询的需要,可以添加复合索引(c1,c2)来提高效率。
小结:
本文整理了一些使用Mysql复合索引时应该注意的知识点。使用的时候可以检查一下你的SQL语句是否去了索引,去了什么索引。
但还要了解的是:
Mysql的执行计划与查询的实际执行过程并不完全一致。不要问我为什么知道,因为我在实践中遇到过。具有不同查询条件的相同SQL语句可能被索引,也可能不被索引。
关于MySQL的综合指数的总结这篇文章到此为止。更多相关MySQL复合索引内容,请搜索我们之前的文章或者继续浏览下面的相关文章。希望你以后能支持我们!