资讯详情

联合索引-最左匹配原则

前言: 面试官:你建索引了吗? 有个朋友:见过! 面试官:你知道MySQL执行计划吗? 我有个朋友:啊? 面试官:那你一定知道最左匹配的原则。 我有一个朋友:额头。 大概每个人在面试中都被问到过这样的问题,事实上,mysql无论是面试还是工作,知识点都是非常重要的一部分。这个简单的介绍MySQL执行优化器最左匹配原匹配原则。

执行优化器,顾名思义,优化句子,准确地说是优化查询句子。事实上,这是我们写的select句子前加一个Explain关键字。

1.创建student并添加信息。

CREATE TABLE `student` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `gid` int(11) NOT NULL,   `cid` int(11) DEFAULT NULL,   `uid` int(11) DEFAULT NULL,   `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,   PRIMARY KEY (`id`),   UNIQUE KEY `uni_Gid_Cid_SId` (`gid`,`cid`,`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

在这里插入图片描述 2.假设gid,cid,uid,对应班级id,课程id,学号id。 1)先不创建索引,使用explain查询。

explain select * from example where name="张三";` 

2)创建gid,cid,uid使用三列联合索引后再使用explain查询

 explain select nme,gid,cid,uid from example where gid=10010;

两条语句的查询结果显然不同,第一条语句因为没有创建name字段索引,所以是全表扫描,第二条语句创建了索引,就走了索引列,查询效率更高。

3.explain优化器返回的字段大概有12个字段。下面是各个字段的含义。

4.type表示对表访问方式,表示MySQL在表中找到所需行的方式,又称“访问类型”。 常用的类型有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)

: 最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。

结论:修改查询列顺序,发现结果一样。是以为MySQL会通过优化器,自动优化索引顺序。

结论:都走了索引。

结论:都是全表扫描,没有走索引。

结论:发现走索引列,但是只是走的gid的单列索引,可以通过key_len来确定走的索引列长度。 前缀:

后缀:

中缀:

结论:如果gid是字符类型,那么前缀匹配用的是索引,后缀和中缀只能全表扫描了(修改gid类型为varchar)

结论:走索引,走的是gid列索引。

结论:索引生效。 结论:索引生效,只匹配gid列索引。

是因为mysql创建联合索引时,首先会对最左边字段排序,也就是第一个字段,然后再在保证第一个字段有序的情况下,再排序第二个字段,以此类推。

所以联合索引最左列是绝对有序的,其他字段无序。

举个例子:可以把联合索引看成“电话簿”,姓名作为联合索引,姓是第一列,名是第二列,当查找人名时,是先确定这个人姓再根据名确定人。只有名没有姓就查不到。

多个单列索引在多条件查询时优化器会选择最优索引策略,可能只用一个索引,也可能将多个索引全用上! 但多个单列索引底层会建立多个 B+索引树,比较占用磁盘空间,也会浪费一定搜索效率,故如果只有多条件联合查询时最好建联合索引!

  1. 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。

  2. 避免在取值朝一个方向增长的字段(例如:日期类型的字段)上,建立索引;对复合索引,避免将这种类型的字段放置在最前面。由于字段的取值总是朝一个方向增长,新记录总是存放在索引的最后一个叶页中,从而不断地引起该叶页的访问竞争、新叶页的分配、中间分支页的拆分。此外,如果所建索引是聚集索引,表中数据按照索引的排列顺序存放,所有的插入操作都集中在最后一个数据页上进行,从而引起插入“热点”。

  3. 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用。因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。

  4. 删除不再使用,或者很少被使用的索引。表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再被需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。

  5. 对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查 询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求;

  6. 不要在有大量相同取值的字段上,建立索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加 快检索速度;

  7. 对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少;

  8. 当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。

1.减少开销。建多个单列索引,每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!

2.覆盖索引。对联合索引(Gid,Cid,UId),如果有如下的sql: select Gid,Cid,UId from student where Gid=1 and Cid=2。那么MySQL可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io操作。减少io操作,特别的随机io其实是dba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。

3.效率高。索引列越多,通过索引筛选出的数据越少。有1000W条数据的表,有如下sql:select from table where Gid=1 and Cid=2 and UId=3,假设假设每个条件可以筛选出10%的数据,如果只有单值索引,那么通过该索引能筛选出1000W10%=100w条数据,然后再回表从100w条数据中找到符合Gid=2 and Cid= 3的数据,然后再排序,再分页;如果是联合索引,通过索引筛选出1000w10% 10% *10%=1w,效率提升很大。

标签: 0871匹配哪种连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台