索引在什么情况下遵循最左前缀的规则?

在创建一个n列的索引时,需要遵循“最左前缀”原则。

创建表:create table abc(a varchar(32) not null, b varchar(32), c date );

创建普通索引:create index in_abc_acb on abc(a, c, b);

1、select * from abc where b=‘bbb‘ and c=sysdate;  不会用到索引,必须要用到左边第一个字段;

2、select * from abc where a like ‘1%‘ and c=sysdate;  a 会用到索引,c 则不会,遇到范围(>、<、between、like)查询就停止匹配;

3、select * from abc where trim(a) = ‘a‘ ; 不会用到索引 ,字段前加了函数(表达式)索引会被抑制。where a = ‘a‘ and c + 1 > sysdate,c不会用到索引,而where a = ‘a‘ and c > sysdate - 2,会用到索引;

4、select * from abc where b like ‘b%‘ and c = sysdate and a=‘a‘ ;acb的索引都可以用到,因为索引是从左到右匹配,in 和 = 可以乱序;

索引的最左前缀原理:

通常我们在建立联合索引的时候,也就是对多个字段建立索引,相信建立过索引的同学们会发现,无论是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‘

这个sql语句是不会走index1索引的

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

这个语句也不会走index1索引。

什么语句会走index1索引呢?

答案是:

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’

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

我们来做个实验:

我这里有一个表:

建立了一个联合索引,prinIdAndOrder里面有三个字段  PARENT_ID, MENU_ORDER, MENU_NAME

接下来测试之前的语句:

EXPLAIN
SELECT 
  t.* 
FROM
  sys_menu t 
WHERE t.`PARENT_ID` = ‘0‘ 
  AND t.`MENU_NAME` = ‘系统工具‘

这一句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字段来的快。不知道我说明白没,感觉这一块说的始终有点牵强。

原文地址:https://www.cnblogs.com/Rivend/p/12099975.html

时间: 2024-11-06 09:33:02

索引在什么情况下遵循最左前缀的规则?的相关文章

MYSQL 索引类型、什么情况下用不上索引、什么情况下不推荐使用索引

mysql explain的使用: http://blog.csdn.net/kaka1121/article/details/53394426 索引类型 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytable表 代码如下: CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL  ); 我们随机向里面插入了10000条记录,其中有一条:5555, admin. 在查找use

SQLSERVER索引在什么情况下会失效

索引并不是时时都会生效的,比如以下几种情况,将导致索引失效: 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因) 注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引 2.对于多列索引,不是使用的第一部分,则不会使用索引 3.like查询是以%开头 4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引 show status like 'Handler_read%';大家可以注意:handler_read_key:这个值

SQL索引是什么?索引的作用是什么?索引的优点是什么?索引的缺点是什么?索引的分类?什么情况下该创建索引?

1.SQL索引是什么?定义:索引(Index)是帮助MySQL高效获取数据的数据结构,就好比书的目录,加快数据库的查询速度. 2.SQL索引的作用是什么?优点是什么?提高查询效率消除数据分组.排序避免“回表”查询(索引覆盖)优化聚合查询用于多表JOIN关联查询利用唯一性约束,保证数据唯一性InnDB行锁实现 3.使用索引的优点(1)可以通过建立唯一索引或者主键索引,保证数据库表中每一行数据的唯一性.(2)建立索引可以大大提高检索的数据,以及减少表的检索行数(3)在表连接的连接条件 可以加速表与表

数据库调优教程(八) 什么情况下不要使用索引

三.           索引 5.      什么情况下不要使用索引 既然索引是有代价的,那么就不要在不应该使用索引的情况下去使用它. 1)    数据唯一性差的字段不要使用索引 比如性别,只有两种可能数据.意味着索引的二叉树级别少,多是平级.这样的二叉树查找无异于全表扫描. 2)    频繁更新的字段不要使用索引 比如logincount登录次数,频繁变化导致索引也频繁变化,增大数据库工作量,降低效率. 3)    字段不在where语句出现时不要添加索引 只有在where语句出现,mysq

什么情况下会导致执行计划不走索引?

不走索引的情况还是蛮多的1.条件字段选择性弱,查出的结果集较大,不走索引:2.where条件等号两边字段类型不同,不走索引:3.优化器分析的统计信息陈旧也可能导致不走索引:4.索引字段 is null 不走索引:5.对于count(*)当索引字段有not null约束时走索引,否则不走索引:6.like 后面的字符当首位为通配符时不走索引:7.使用不等于操作符如:<>.!= 等不走索引:8.索引字段前加了函数或参加了运算不走索引:什么情况下会导致执行计划不走索引?

数据库----问题1:数据库索引底层是怎样实现的,哪些情况下索引会失效?

什么是索引: 一个索引是存储的表中一个特定列的值数据结构(最常见的是B-Tree).索引是在表的列上创建.所以,要记住的关键点是索引包含一个表中列的值,并且这些值存储在一个数据结构中.请记住记住这一点:索引是一种数据结构 . 哈希索引的缺点: 优点:在寻找值时哈希表效率极高,如果使用哈希索引,对于比较字符串是否相等的查询能够极快的检索出的值. 缺点:哈希表是无顺的数据结构,对于很多类型的查询语句哈希索引都无能为力.比如无法查询所有小于40岁的员工.因为哈希表只适合查询键值对-也就是说查询相等的查

MySQL数据库中的索引(二)——索引的使用,最左前缀原则

上文中,我们了解了MySQL不同引擎下索引的实现原理,在本文我们将继续探讨一下索引的使用以及优化. 创建索引可以大大提高系统的性能. 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性. 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因. 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义. 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间. 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能.

MySQL分页优化中的“INNER JOIN方式优化分页算法”到底在什么情况下会生效?

本文出处:http://www.cnblogs.com/wy123/p/7003157.html 最近无意间看到一个MySQL分页优化的测试案例,并没有非常具体地说明测试场景的情况下,给出了一种经典的方案,因为现实中很多情况都不是固定不变的,能总结出来通用性的做法或者说是规律,是要考虑非常多的场景的,同时,面对能够达到优化的方式要追究其原因,同样的做法,换了个场景,达不到优化效果的,还要追究其原因.个人对此场景在不用情况表示怀疑,然后自己测试了一把,果然发现一些问题,同时也证实了一些预期的想法.

mysql什么情况下会触发表锁

锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议. MySQL锁概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著