精华内容
下载资源
问答
  • 之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和面试官交流,发现遗漏了些东西,这里自己整理一下这方面的内容。 最左前缀匹配原则 在mysql建立联合索引时会遵循...
  • 主要给大家介绍了关于MySQL组合索引最左匹配原则的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mysql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • 深入浅析Mysql联合索引原理最左匹配原则

    万次阅读 多人点赞 2019-04-28 11:38:46
    之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和大牛交流中,发现遗漏了些东西,这里自己整理一下这方面的内容。 最左前缀匹配原则 在mysql建立联合索引时会遵循...

    前言

    之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和大牛交流中,发现遗漏了些东西,这里自己整理一下这方面的内容。

    最左前缀匹配原则

    在mysql建立联合索引时会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配,

    示例:

    CREATE TABLE `student` (
      `Id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增Id',
      `Gid` int(11) unsigned DEFAULT NULL COMMENT '年级id',
      `Cid` int(11) unsigned DEFAULT NULL COMMENT '班级id',
      `SId` int(11) unsigned DEFAULT NULL COMMENT '学号',
      `Name` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '姓名',
      PRIMARY KEY (`Id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
    
    

    对列Gid、列Cid和列Sid建一个联合索引

    create unique index uni_Gid_Cid_SId on student(Gid,Cid,SId)

    联合索引 uni_Gid_Cid_SId 实际建立了(Gid)、(Gid,Cid)、(Gid,Cid,SId)三个索引。

    插入模拟数据

    INSERT INTO `student` (`Gid`, `Cid`, `SId`, `Name`) VALUES (floor(rand() * rand() *rand() * 1000000000) , floor(rand() *  rand() *rand() * 1000000000) , floor(rand() * rand() * rand() *1000000000) , rand());

    查询实例:

    SELECT * FROM student WHERE Gid=68778 AND Cid=465176354 AND Name='0.56437948'

    上面这个查询语句执行时会依照最左前缀匹配原则,检索时会使用索引(Gid,Cid)进行数据匹配。

    注意

    索引的字段可以是任意顺序的,如:

    SELECT * FROM student WHERE Gid=68778      AND Cid=465176354 ;
    SELECT * FROM student WHERE Cid=465176354  AND Gid=68778;

    这两个查询语句都会用到索引(Gid,Cid),mysql创建联合索引的规则是首先会对联合合索引的最左边的,也就是第一个字段Gid的数据进行排序,在第一个字段的排序基础上,然后再对后面第二个字段Cid进行排序。其实就相当于实现了类似 order by Gid Cid这样一种排序规则。

    有人会疑惑第二个查询语句不符合最左前缀匹配:首先可以肯定是两个查询语句都保函索引(Gid,Cid)中的GidCid两个字段,只是顺序不一样,查询条件一样,最后所查询的结果肯定是一样的。既然结果是一样的,到底以何种顺序的查询方式最好呢?此时我们可以借助mysql查询优化器explain,explain会纠正sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。

    那么问题产生了?既然结果是一样的,到底以何种顺序的查询方式最好呢?

    所以,而此时那就是我们的mysql查询优化器该登场了,sql语句中字段的顺序不需要和联合索引中定义的字段顺序一致,查询优化器会自己调整顺序,mysql查询优化器会判断纠正这条sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。所以,当然是我们能尽量的利用到索引时的查询顺序效率最高咯,所以mysql查询优化器会最终以这种顺序进行查询执行。

    为什么要使用联合索引

    减少开销。建一个联合索引(Gid,Cid,SId),实际相当于建了(Gid)、(Gid,Cid)、(Gid,Cid,SId)三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!

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

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

    缺点。联合索引越多,索引列越多,则创建的索引越多,索引都是存储在磁盘里的,通过索引算法(Btree代表索引算法使用二叉树的形式来做索引的)来查找数据,的确可以极大的提高查询效率,但是与此同时增删改的同时,需要更新索引,同样是需要花时间的,并且索引所占的磁盘空间也不小。

    建议。单表尽可能不要超过一个联合索引,单个联合索引不超过3个字段。

    引申

    对于联合索引(Gid,Cid,SId),查询语句SELECT * FROM student WHERE Cid = 465176354 ;是否能够触发索引?
    大多数人都会说NO,实际上却是YES。

    原因:

    EXPLAIN SELECT * FROM student WHERE SId=465176354;
    EXPLAIN SELECT * FROM student WHERE Gid=68778 

    观察上述两个explain结果中的type字段。查询中分别是:

    index:这种类型表示mysql会对整个该索引进行扫描。要想用到这种类型的索引,对这个索引并无特别要求,只要是索引,或者某个联合索引的一部分,mysql都可能会采用index类型的方式扫描。但是呢,缺点是效率不高,mysql会从索引中的第一个数据一个个的查找到最后一个数据,直到找到符合判断条件的某个索引。所以,上述语句会触发索引。


    ref:这种类型表示mysql会根据特定的算法快速查找到某个符合条件的索引,而不是会对索引中每一个数据都进行一一的扫描判断,也就是所谓你平常理解的使用索引查询会更快的取出数据。而要想实现这种查找,索引却是有要求的,要实现这种能快速查找的算法,索引就要满足特定的数据结构。简单说,也就是索引字段的数据必须是有序的,才能实现这种类型的查找,才能利用到索引。

    总结

    以上所述是给大家介绍的mysql联合索引最左匹配原则,希望对大家有所帮助

    展开全文
  • 2、1)查询字段是索引中字段,但是查询条件排列不符合最左原则,结果使用到了建立的索引。 3、1)查询字段为索引中的全部字段(非索引顺序),查询条件为非索引字段,结果没用到索引 2)查询字段为...

    Mysql(版本5.6.29)数据库使用InnoDb引擎,建表语句如下,插入10w条数据(没设置主键,但是表中id是唯一的);

    CREATE TABLE `test` (

      `id` int(10) NOT NULL,

      `name` varchar(10) DEFAULT NULL COMMENT '姓名',

      `age` int(10) DEFAULT NULL COMMENT '年龄',

      `ovd_int_amt` decimal(17,2) DEFAULT NULL COMMENT '逾期利息金额',

      `addr` varchar(100) DEFAULT NULL COMMENT '地址',

      `sex` varchar(2) DEFAULT NULL COMMENT '性别',

      `grade` int(5) DEFAULT NULL COMMENT '成绩',

      KEY `idx003` (`name`,`addr`,`id`) USING BTREE

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

     

    建立如下联合索引:

    1、查询字段不是索引中字段,且使用联合索引中的部分字段(第三个字段和第一个字段)做为查询条件,使用EXPLAIN EXTENDED SQL,结果:使用到了idx003索引;

    EXPLAIN EXTENDED

    SELECT age,grade FROM test WHERE id <=10 AND `name`='7e36de8e95';

     

     

    2、1)查询字段是索引中字段,但是查询条件排列不符合最左原则,结果使用到了建立的索引。

    3、1)查询字段为索引中的全部字段(非索引顺序),查询条件为非索引字段,结果没用到索引

    2)查询字段为索引中的全部字段(索引顺序),查询条件为非索引字段,结果没用到索引

    3)查询字段为索引中的部分字段(按索引顺序)和非索引字段【索引字段和非索引字段交换顺序也不能用到索引】,查询条件为索引字段,结果没用到索引;

    展开全文
  • mysql联合索引最左匹配原则的底层实现原理 要看懂,需要熟悉mysql b+ tree的数据结构 b+tree的叶节点和叶子节点的排序特性是按照,从小到大,从到右的这么一个规则,int直接比大小,uuid比较ASCII码, 联合索引的排序...

    mysql联合索引最左匹配原则的底层实现原理

    要看懂,需要熟悉mysql b+ tree的数据结构

    b+tree的叶节点和叶子节点的排序特性是按照,从小到大,从左到右的这么一个规则,int直接比大小,uuid比较ASCII码,

    • 联合索引的排序规则

      拿a_b_c_idx为例,优先比较a列的大小,如果a列的大小相等,才会去看b列的大小,否则直接按照a列排序,以此类推.

    • 假如直接拿 b='xxx’作为条件

      在遍历索引树的时候,到页子节点,不能保证索引的顺序,还是要去全文遍历其他的叶子结点

    展开全文
  • 我们容易有以一个误区,就是在经常使用的查询条件上都建立索引索引越多越好,那到底是不是这样呢? 在讲正文之前,我们先来看一个重要的属性列的离散度,公式如下: count(distinct(column_name)) : count(*) --列...

    准备工作,下面的演示都是基于user_innodb表:

    DROP TABLE IF EXISTS `user_innodb`;
    CREATE TABLE `user_innodb` (
      `id` bigint(64) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) NOT NULL,
      `gender` tinyint(1) NOT NULL,
      `phone` varchar(11) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    

    1.联合索引与最左前缀原则

    在平时开发中,我们最常见的是单列索引(比如主键primary key),但在我们需要多条件查询的时候,也会建立联合索引。单列索引可以看成是特殊的联合索引。比如我们在user表上面,给name和phone建立了一个联合索引。

    ALTER TABLE 可以用来创建索引,包括普通索引、UNIQUE索引或PRIMARY KEY索引:

    • ALTER TABLE table_name ADD INDEX index_name (column_list)

    • ALTER TABLE table_name ADD UNIQUE (column_list)

    • ALTER TABLE table_name ADD PRIMARY KEY (column_list)

    ALTER TABLE user_innodb add INDEX comidx_name_phone(name,phone); -- 创建联合索引
    

    1.1 联合索引是怎么组织的?

    下图是B+Tree的索引结构,是一个单值索引:

    在这里插入图片描述
    我们可以看到,所有非叶子结点的构成都是由两部分组成,索引值+指针,而单值索引说的就是在索引值这里就只有一个值(比如id),而联合索引在索引值可能会有多个值(比如name和phone)

    在这里插入图片描述

    相比于单值索引:

    1. 联合索引在 B+Tree 中是复合的数据结构
    2. 由于 B+树本身是有序的,所以联合索引是从左到右的顺序来建立搜索树的(name在左边,phone在右边)。从上图可以看出来,name是有序的,phone是无序的。当name相等的时候,phone才是有序的。
    3. 当存储引擎是InnoDB时,叶节点存储的是数据/主键

    问题一:联合索引是怎么查找数据的?

    比如,我们使用 where name=‘Bob’ and phone = ‘132xx’ 去查询数据的时候

    1. B+Tree 会优先比较 name 来确定下一步应该搜索的方向,往左还是往右
    2. 如果 name相同的时候再比较 phone

    但是如果查询条件没有name,就不知道第一步应该查哪个节点,因为建立搜索树的时候name是第一个比较因子,所以用不到索引。

    问题二:联合索引与单值索引什么关系?

    假设我们的项目里面有两个查询很慢:

    SELECT * FROM user_innodb WHERE name= ?;
    SELECT * FROM user_innodb WHERE name= ? AND phone=?;
    

    按照我们的想法,一个查询创建一个索引,所以我们针对这两条SQL创建了两个索引,这种做法觉得正确吗?

    CREATE INDEX idx_name on user_innodb(name); 
    CREATE INDEX idx_name_phoneonuser_innodb(name,phone);
    

    当我们创建一个联合索引的时候,用左边的字段name去查询的时候,也能用到索引,所以单独为name创建一个索引完全没必要。相当于建立了两个联合索引(name)、(name,phone)。

    如果我们创建三个字段的索引index(a,b,c),相当于创建三个索引:index(a)、index(a,b)、index(a,b,c)。用 where b=? 和 where b=? and c=? 和where a=? and c=?是不能使用到索引的。因为不能不用第一个字段,不能中断。

    1.2 最左前缀原则

    因为联合索引中包含了多个字段,所以不能像单值索引那样直接使用就行。那需要遵守什么规则呢?
    答:最左前缀原则:带头大哥不能死,中间兄弟不能断。

    我们在建立联合索引的时候,一定要把最常用的列放在最左边。比如下面的三条语句,能用到联合索引吗?

    1. 使用两个字段,可以用到联合索引(注:两个字段的顺序颠倒并不影响,因为全值匹配时mysql会优化字段顺序)
    EXPLAIN SELECT * FROM user_innodb WHERE name= '张三' AND phone='12345678910'
    

    在这里插入图片描述

    1. 使用左边的name字段,可以用到联合索引:
    EXPLAIN SELECT * FROM user_innodb WHERE name= '张三'
    

    在这里插入图片描述

    1. 使用右边的phone字段,无法使用索引,全表扫描:
    EXPLAIN SELECT * FROM user_innodb WHERE name= '12345678910'
    

    在这里插入图片描述

    从联合索引的结构中,我们看到了索引是已经排好序的,那我们如在遵守最左前缀原则的前提下,order by时用到索引(避免 filesort)?

    • 使用形式一:order by 索引最前列 ==> 整体有序。
    • 使用形式二:where + order by索引列 ==> 局部有序(为了最左前缀原则,尽量order by索引列(用where 保证中间不断开))


    再说一句,分组(group by)的实质是先排序后分组,原则类似order by。where 高于 having,where中能限定但条件不要去having中限定

    另外,不要在索引上做任何操作,因为可能会导致索引失效,转而全表扫描。

    1.3 什么情况下会索引失效?

    当索引列出现以下六种操作时常常出现索引失效:

    1. 使用函数(replace\SUBSTR\CONCAT\sum count avg)、表达式、计算(+ - * /)。因为当前值改变后就无法与索引存的值匹配上。
    SELECT * FROM user_innodb where left(name, 3)='张三';-- left函数是一个字符串函数,它返回具有指定长度的字符串的左边部分
    
    1. 使用范围查询(!=,<=>,in)会导致右边列失效。因为二叉树的查找是 = 查找,若是一个范围的话无法继续下探。
      • 最左列用范围,该列也不会使用索引,全部索引列失效
      • 其余列用范围,当前列仍会使用索引,但右边索引列失效
    SELECT * FROM user_innodb where name='张三' and age > 22;
    
    1. like以通配符开头(’%abc…’),mysql索引失效会变成全表扫描操作。因为无法判断%代表多少字符。
      • 方案一:like (‘abc%’)
      • 方案二:覆盖索引
    SELECT * FROM user_innodb where name like '%三';
    
    1. 字符串不加’ '索引失效。因为会出现出现隐式转换,相当于给索引列做了操作。
    SELECT * FROM user_innodb where name = 007;-- "007"从字符串变成了数字007
    
    1. 少用or,用它连接时很多情况下索引会失效
    SELECT * FROM user_innodb where name = '张三' or name = '李四';
    
    1. is null,is not null 无法使用索引
    SELECT * FROM user_innodb where name is null;
    

    ==> 对这一部分内容通过一首打油诗做个总结:

    							全值匹配我最爱,最左前缀要遵守
    							带头大哥不能死,中间兄弟不能断
    							索引列上少计算,范围之后全失效
    							like百分写最右,覆盖索引不写星
    						    不等空值还有or,索引失效要少用
    

    2.覆盖索引

    回表:非主键索引,我们先通过索引找到主键索引的键值,再通过主键值查出索引里面没有的数据,它比基于主键索引的查询多扫描了一棵索引树,这个过程就叫回表。例如:select * from user_innodb where name = ‘青山’;

    在这里插入图片描述

    在辅助索引里面,不管是单列索引还是联合索引,如果select的数据列只用从索引中就能够取得,不必从数据区中读取,这时候使用的索引就叫做覆盖索引,这样就避免了回表。

    我们先来创建一个联合索引:

    CREATE INDEX idx_name_phoneonuser_innodb(name,phone);
    

    这三个查询语句都用到了覆盖索引:

    EXPLAIN SELECT name,phone FROM user_innodb WHERE name='青山' AND phone='13666666666';
    EXPLAIN SELECT name FROMuser_innodb WHERE name='青山' AND phone='13666666666'; 
    EXPLAIN SELECT phone FROM user_innodb WHERE name='青山' AND phone='13666666666';
    

    在这里插入图片描述

    Extra里面值为“Using index”代表使用了覆盖索引。另外,select * ,用不到覆盖索引。很明显,因为覆盖索引减少了IO次数,减少了数据的访问量,可以大大地提升查询效率。

    3.索引条件下推(ICP)

    在讲ICP前,我们再创建一张数据表(员工表),并且在last_name和first_name上面创建联合索引。

    CREATE TABLE `employees`( 
        `emp_no`int(11)NOTNULL,
        `birth_date`date NULL,
        `first_name`varchar(14)NOTNULL,
        `last_name`varchar(16)NOTNULL, 
        `gender`enum('M','F')NOTNULL, 
        `hire_date`date NULL, 
        PRIMARYKEY(`emp_no`)
    )ENGINE=InnoDBDEFAULTCHARSET=latin1;
    
    alter table employees add index idx_lastname_firstname(last_name,first_name); -- 创建联合索引
    
    INSERT INTO `employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(1, NULL,'698','liu','F',NULL); 
    INSERT INTO `employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(2, NULL,'d99','zheng','F',NULL); 
    INSERT INTO `employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(3, NULL,'e08','huang','F',NULL); 
    INSERT INTO `employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(4, NULL,'59d','lu','F',NULL); 
    INSERT INTO` employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(5, NULL,'0dc','yu','F',NULL); 
    INSERT INTO` employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(6, NULL,'989','wang','F',NULL); 
    INSERT INTO` employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(7, NULL,'e38','wang','F',NULL); 
    INSERT INTO` employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(8, NULL,'0zi','wang','F',NULL); 
    INSERT INTO` employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(9, NULL,'dc9','xie','F',NULL); 
    INSERT INTO` employees`(`emp_no`,`birth_date`,`first_name`,`last_name`,`gender`,`hire_date`)VALUES(10, NULL,'5ba','zhou','F',NULL);
    

    3.1 ICP是干什么用的?

    现在我们要查询所有姓wang,并且名字最后一个字是zi的员工,比如王胖子,王瘦子。查询的SQL如下:

    select * from employees where last_name='wang' and first_name LIKE '%zi';
    

    这条SQL有两种执行方式:

    1. 根据联合索引查出所有姓wang的二级索引数据,然后回表,到主键索引上查询全部符合条件的数据(3 条数据)。然后返回给 Server 层,在 Server 层过滤出名字以zi结尾的员工。

      注:索引的比较是在存储引擎进行的,数据记录的比较是在Server层进行的。而当first_name的条件不能用于索引过滤时,Server 层不会把first_name的条件传递给存储引擎,所以读取了两条没有必要的记录。如果将数据规模扩大,比如满足last_name='wang’的记录有100000条,就会有99999条没有必要读取的记录。

    在这里插入图片描述

    1. 根据联合索引查出所有姓wang的二级索引数据(3个索引),然后从二级索引中筛选出first_name以zi结尾的索引(1个索引),然后再回表,到主键索引上查询全部符合条件的数据(1条数据),返回给Server 层。

    很明显,第二种方式到主键索引上查询的数据更少,但mysql在没开启ICP前使用的都是第一种。

    explain select * from employees where last_name='wang' and first_name LIKE '%zi';
    

    在这里插入图片描述

    Using Where代表从存储引擎取回的数据不全部满足条件,需要在Server 层过滤。先用last_name 条件进行索引范围扫描,读取数据表记录,然后进行比较,检查是否符合first_name LIKE ‘%zi’ 的条件。此时3条中只有1条符合条件。

    3.2 怎么开启ICP?

    开启命令如下:

    set optimizer_switch='index_condition_pushdown=on';
    

    开启后再查看此时的执行计划,Using index condition:

    在这里插入图片描述

    把first_name LIKE '%zi’下推给存储引擎后,只会从数据表读取所需的1条记录。索引条件下推(IndexConditionPushdown),5.6以后完善的功能。只适用于二级索引。ICP 的目标是减少访问表的完整行的读数量从而减少 I/O 操作。

    展开全文
  • 联合索引最左匹配原则

    万次阅读 热门讨论 2019-01-05 17:05:24
    如果有一个2列的索引(col1,col2),则已经对(col1)、(col1,col2)上建立了索引; 如果有一个3列索引(col1,col2,col3),则已经对(col1)、(col1,col2)、(col1,col2,col3)上建立了索引; 例如: 组合索引(a,b) explain...
  • 注意:比较一下第2个sql语句和第8个sql语句,二者的区别在于: 1>第2个sql语句查询了非索引列sex,故根据最左原则,无法使用该索引; 2>第8个sql语句只查询了索引列,(若只查询索引列,则只需扫描索引树即可)故可以...
  • 索引的最左前缀原理: 通常我们在建立联合索引的时候,也就是对多个字段建立索引,相信建立过索引的同学们会发现,无论是oralce还是mysql都会让我们选择索引的顺序,比如我们想在a,b,c三个字段上建立一个联合索引,...
  • 最近在看MySQL索引的知识,看到组合索引的时候,有一个左侧原则,我就建了个简单的表验证一下,过程中碰到有些不懂的,在这里求教一下,mysql版本5.7的CREATE TABLE `testp` (`id` int(10) unsigned NOT NULL AUTO...
  • 组合索引的选择原则

    2021-05-04 05:27:07
    表上的索引是根据什么建立的,特别是组合索引,有多个的时候优化器又怎么选择使用哪个呢,今天做个试验验证下新建这个表testindex表结构Name Type Nullable Default Comments---------- ------------- -------- ----...
  • 主要给大家介绍了关于mysql索引最左原则的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mysql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • Mysql联合索引最左匹配原则

    千次阅读 2019-01-21 14:03:13
    之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和面试官交流,发现遗漏了些东西,这里自己整理一下这方面的内容。 最左前缀匹配原则 在mysql建立联合索引时会遵循...
  • 索引6:联合索引最左匹配原则

    千次阅读 2020-02-13 18:17:48
    联合索引最左匹配原则 什么是最左匹配原则? 举例 索引列A和列B 建立联合索引 index(A,B)(A,B顺序有序) explain select X from XX where A=’‘and B=’’ 走 ab索引 explain select X from XX where A=’‘走 ab...
  • MySQL索引最左匹配原则及优化原理

    千次阅读 2020-07-17 00:07:12
    (2) 定义有外键的列一定要建立索引 : 外键列通常用于表与表之间的连接,在其上创建索引可以加快表间的连接 (3) 对于经常查询的数据列最好建立索引 ① 对于需要在指定范围内快速或频繁查询的数据列,因为索引已经排序...
  • B+Tree联合索引底层数据结构 单列索引:是指由一个字段(单个列)组成的索引; 联合索引联合索引又叫复合索引,是指由多个字段(字段是有顺序的)组成的索引,比如: CREATE TABLE users ( id int(11) NOT NULL ...
  • 软件版本mysql5.7根据官网的文档 https://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html查询条件要符合最左原则才能使用到索引首先说说联合索引的好处:覆盖索引,这一点是重要的,众所周知非...
  • MySQL 索引最左前缀原则 索引最佳前缀法则:带头大哥不能死、中间兄弟不能断 1、准备数据 建表 CREATE TABLE IF NOT EXISTS staff ( id INT PRIMARY KEY auto_increment, name VARCHAR(50), age INT, pos ...
  • 上一篇文章《MySQL索引那些事》主要讲了MySQL索引的底层原理,且对比了B+Tree作为索引底层数据结构相对于其他数据结构(二叉树、...为什么会有最左前缀匹配原则 在分享这篇文章之前,我在网上查了关于MySQL联合索引在B+
  • mysql索引最左匹配原则的理解

    万次阅读 多人点赞 2018-09-04 17:00:05
    建立了联合索引(a,b,c) 验证: explain 指令详解可以查看 https://www.cnblogs.com/gomysql/p/3720123.html explain select * from test where a; explain select * from test where a; ...
  • 最左匹配原则的底层原理

    千次阅读 多人点赞 2020-09-10 00:55:52
    什么是最左匹配原则 顾名思义:最左优先,以左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。 例如:如果建立(a,b)顺序的索引,我们的条件只有b=xxx,是匹配不...
  • MySQL 最左原则的理解

    千次阅读 2020-09-16 01:12:39
    1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,...
  • 最左匹配原则 联合索引 我们也可以同时以多个列的大小作为排序规则,也就是同时为多个列建立索引,比方说我们想让B+树按照c2和c3列的大小进行排序,这个包含两层含义: 先把各个记录和页按照c2列进行排序。 在...
  • 索引最左匹配原则

    2021-01-14 15:23:58
    我在上大学的时候就听说过数据库的最左匹配原则,当时是通过各大博客论坛了解的,但是这些博客的局限性在于它们对最左匹配原则的描述就像一些数学定义一样,往往都是列出123点,满足这123点就能匹配上索引,否则就不...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,440
精华内容 4,576
关键字:

联合索引最左原则原理