• mysql最左前缀原则


    为什么要有索引 

      假设我们要查找以下SQL语句,如果没有索引我们就会扫描整张物理表

    SELECT `uid` FROM people WHERE lname`='Liu'  AND `fname`='Zhiqun' AND `age`=26 

       假设建有单列索引index(lname),那么系统就会先到lname索引表中查找得到符合条件的people主键值,然后通过主键值扫描people表,进行剩下的匹配,这样就大大地提高效率。

      为了提高搜索效率,我们需要考虑运用多列索引,由于索引文件以B-Tree格式保存,所以我们不用扫描任何记录,即可得到最终结果。

    索引的最左前缀原理:

      通常我们在建立联合索引的时候,也就是对多个字段建立索引,相信建立过索引的同学们会发现,无论是oralce还是mysql都会让我们选择索引的顺序,比如我们想在a,b,c三个字段上建立一个联合索引,我们可以选择自己想要的优先级,a、b、c,或者是b、a、c 或者是c、a、b等顺序。为什么数据库会让我们选择字段的顺序呢?不都是三个字段的联合索引么?这里就引出了数据库索引的最左前缀原理。

      比如:索引index1:(a,b,c)有三个字段,我们在使用sql语句来查询的时候,会发现很多情况下不按照我们想象的来走索引。比如以下两种情况

    select * from table where c = '1'
    select * from table where b =‘1’ and c ='2' 

      以下三种会走索引

    select * from table where a = '1'  
    
    select * from table where a = '1' and b =2’  
    
    select * from table where a = '1' and b =2’  and c='3'

      从以上两个代码组可知看出,所有走索引index1的sql语句的查询条件里面都带有a字段,那么问题来了,index1的索引的最左边的列字段是a,是不是查询条件中包含a就会走索引呢?例如:

    select * from table where a = '1' and c=2

      按照之前的理解,包含a字段,会走索引,但是是不是所有字段都走了索引呢?

    我们来做个实验:

      我这里有一个表

     

      接下来测试之前的语句:

    EXPLAIN select * from indextest where a = 2 and c = "艳 耀 董"

      这一句sql就相当于之前的select * from table where a = '1' and c= ‘2’这个sql语句了,我们来看看解释计划:

      可以看到走了索引prinIdAndOrder,但是旁边的key_len=303,但道理key_len应该是大于303的,为什么呢?

      因为PARENT_ID字段的类型是varchar(100) NULL,所以key_len=100*3+2+1=303,但是还有MENU_NAME呢!具体的key_len的计算方法,大家可以百度,我的表的字符集是utf-8,不同字符集的表的计算方式不一样。这里的解释计划显示key_len只有303,说明只是走了字段PARENT_ID的索引,没有走MENU_NAME的索引。

      这也是最左前缀原理的一部分,索引index1:(a,b,c),只会走a、a,b、a,b,c 三种类型的查询,其实这里说的有一点问题,a,c也走,但是只走a字段索引,不会走c字段。

    另外还有一个特殊情况说明下,select * from table where a = '1' and b > ‘2’  and c='3' 这种类型的也只会有 a与b 走索引,c不会走。

      像select * from table where a = '1' and b > ‘2’  and c='3' 这种类型的sql语句,在a、b走完索引后,c肯定是无序了,所以c就没法走索引,数据库会觉得还不如全表扫描c字段来的快。不知道我说明白没,感觉这一块说的始终有点牵强。

      最左前缀:顾名思义,就是最左优先,上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。 

     最左侧规范

      (1)在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。

      

     最左前缀是什么?

      最左前缀是针对组合索引而言的,那么组合索引有什么好处?

        以index (a,b,c)为例建立这样的索引相当于建立了索引a、ab、abc三个索引。一个索引顶三个索引当然是好事,毕竟每多一个索引,都会增加写操作的开销和磁盘空间的开销。

        最左前缀:顾名思义,就是最左优先,上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。 

  • 相关阅读:
    mysql字符集
    zabbix自动发现zabbix_agent后添加到所属组和链接到某些模块(九)
    zabbix_agent添加到系统服务启动(八)
    苦苦的追寻,奈何~~(一年三份工作的总结)
    systemd service 设置limit,不生效问题
    logrotate
    cron定时任务
    crontab定时任务第一个周期未完成下一个周期执行就来了
    来年仍旧迷茫...
    rsync的daemon模式
  • 原文地址:https://www.cnblogs.com/AbnerLc/p/11927163.html
Copyright © 2020-2023  润新知