联合索引最左匹配原则

什么时候创建组合索引?

当我们的where查询存在多个条件查询的时候,我们需要对查询的列创建组合索引

为什么不对每一列创建索引

  • 减少开销
  • 覆盖索引
  • 效率高

减少开销:假如对col1、col2、col3创建组合索引,相当于创建了(col1)、(col1,col2)、(col1,col2,col3)3个索引

覆盖索引:假如查询SELECT col1, col2, col3 FROM 表名,由于查询的字段存在索引页中,那么可以从索引中直接获取,而不需要回表查询

效率高:对col1、col2、col3三列分别创建索引,MySQL只会选择辨识度高的一列作为索引。假设有100w的数据,一个索引筛选出10%的数据,那么可以筛选出10w的数据;对于组合索引而言,可以筛选出100w10%10%*10%=1000条数据

最左匹配原则

只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合,所以在建立联合索引的时候查询最频繁的条件要放在左边

假设我们创建(col1,col2,col3)这样的一个组合索引,那么相当于对col1列进行排序,也就是我们创建组合索引,以最左边的为准,只要查询条件中带有最左边的列,那么查询就会使用到索引

创建测试表

CREATE TABLE `student` (
  `id` int(11) NOT NULL,
  `name` varchar(10) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_id_name_age` (`id`,`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

填充100w测试数据

DROP PROCEDURE pro10;
CREATE PROCEDURE pro10()
BEGIN
    DECLARE i INT;
    DECLARE char_str varchar(100) DEFAULT ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789‘;
    DECLARE return_str varchar(255) DEFAULT ‘‘;
    DECLARE age INT;
    SET i = 1;
    WHILE i < 5000000 do
        SET return_str = substring(char_str, FLOOR(1 + RAND()*62), 8);
        SET i = i+1;
        SET age = FLOOR(RAND() * 100);
        INSERT INTO student(id, name, age) values(i, return_str, age);
    END WHILE;
END;
CALL pro10();

场景测试

EXPLAIN SELECT * FROM student WHERE id = 2;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE id = 2 AND name = ‘defghijk‘;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE id = 2 AND name = ‘defghijk‘ and age = 8;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE id = 2 AND age = 8;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE name = ‘defghijk‘ AND age = 8;

可以看到该查询没有使用到索引,类型为index,查询行数为4989449,几乎进行了全表扫描,由于组合索引只针对最左边的列进行了排序,对于name、age只能进行全部扫描

EXPLAIN SELECT * FROM student WHERE name = ‘defghijk‘ AND id = 2;
EXPLAIN SELECT * FROM student WHERE age = 8 AND id = 2;
EXPLAIN SELECT * FROM student WHERE  name = ‘defghijk‘ and age = 8 AND id = 2;
复制代码

可以看到如上查询也使用到了索引,id放前面和放后面查询到的结果是一样的,MySQL会找出执行效率最高的一种查询方式,就是先根据id进行查询

总结

如上测试,可以看到只要查询条件的列中包含组合索引最左边的那一列,不管该列在查询条件中的位置,都会使用索引进行查询。下图的查询我的meta_key和另一个字段meta_id有联合索引,meta_value是普通字段,可以看到是使用了

欢迎各路英雄好汉指正文中的错误!

转载于:https://juejin.im/post/5c862b3ff265da2dda698456

来自为知笔记(Wiz)

原文地址:https://www.cnblogs.com/hualou/p/12163941.html

时间: 2024-07-31 04:38:33

联合索引最左匹配原则的相关文章

联合索引最左匹配

假设有联合索引 idx1(a,b,c) 下面的SQL可完整用到索引. 1.SELECT ... WHERE b=? AND c=? AND a=?; 2.SELECT ... WHERE b=? AND a=? AND c=?; 3.SELECT ... WHERE a=? AND b IN(?,?) AND c=?; 4.SELECT ... WHERE a=? AND b=? ORDER BY c; 5.SELECT ... WHERE a=? AND b IN(?,?) ORDER BY

【转】Mysql索引最左匹配原则理解

作者:沈杰 链接:https://www.zhihu.com/question/36996520/answer/93256153来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 这是你的表结构,有三个字段,分别是id,name,cid CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `cid` int(11) DEFAUL

【转】mysql索引最左匹配原则的理解

作者:沈杰 链接:https://www.zhihu.com/question/36996520/answer/93256153 来源:知乎 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `cid` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name_cid_INX` (`name`,`cid`),

Mysql最左匹配原则实践(原创)

mysql最左匹配原则 什么叫最左匹配原则 最左匹配原则的误区 实战 结论: 1 条件查询中条件顺序没有关系 2 在最左匹配原则中,有如下说明: 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>.<.between.like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整. =和in可以乱

Mysql中联合索引的最左匹配原则(百度)

创建联合索引时列的选择原则 经常用的列优先(最左匹配原则) 离散度高的列优先(离散度高原则) 宽度小的列优先(最少空间原则) 在Mysql建立多列索引(联合索引)有最左前缀的原则,即最左优先.如果我们建立了一个2列的联合索引(col1,col2),实际上已经建立了两个联合索引(col1).(col1,col2);如果有一个3列索引(col1,col2,col3),实际上已经建立了三个联合索引(col1).(col1,col2).(col1,col2,col3). 解释 1.b+树的数据项是复合的

最左匹配原则

1.简单说下什么是最左匹配原则顾名思义:最左优先,以最左边的为起点任何连续的索引都能匹配上.同时遇到范围查询(>.<.between.like)就会停止匹配.例如:b = 2 如果建立(a,b)顺序的索引,是匹配不到(a,b)索引的:但是如果查询条件是a = 1 and b = 2或者a=1(又或者是b = 2 and b = 1)就可以,因为优化器会自动调整a,b的顺序.再比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,

联合索引在B+树上的存储结构及数据查找方式

能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 引言 上一篇文章<MySQL索引那些事>主要讲了MySQL索引的底层原理,且对比了B+Tree作为索引底层数据结构相对于其他数据结构(二叉树.红黑树.B树)的优势,最后还通过图示的方式描述了索引的存储结构.但都是基于单值索引,由于文章篇幅原因也只是在文末略提了一下联合索引,并没有大篇幅的展开讨论,所以这篇文章就单独去讲一下联合索引在B+树上的存储结构.本文主要讲解的内容有: 联合索引在B+树

mysql联合索引详解

所有的MySQL列类型能被索引.在相关的列上的使用索引是改进SELECT操作性能的最好方法. 一.前缀索引 对于CHAR和VARCHAR列,你可以索引列的前缀.这更快并且比索引整个列需要较少的磁盘空间.在CREATE TABLE语句中索引列前缀的语法看起来像这样: KEY index_name (col_name(length))下面的例子为name列的头10个字符创建一个索引: mysql> CREATE TABLE test (name CHAR(200) NOT NULL,KEY inde

mysql 什么时候用单列索引?什么使用用联合索引?

我一个表 students 表,有3个字段 ,id,name,age 我要查询 通过 name 和age,在这两个字段 是创建 联合索引?还是分别在nage和age上创建 单列索引呢? 多个字段查询什么情况下用联合索引 什么时候分别创建单列索引呢? 作者:范孝鹏链接:https://www.zhihu.com/question/40736083/answer/88191544来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 1,首先要确定优化的目标,在什么样的业务场