zoukankan      html  css  js  c++  java
  • 联合索引最左匹配原则

    什么时候创建组合索引?

    当我们的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





  • 相关阅读:
    视频测试序列的下载地址【转】
    RDO、SAD、SATD、λ相关概念【转】
    RGB、YUV和YCbCr介绍【转】
    H.264和HEVC分析软件和工具【转】
    Mysql——Innodb和Myisam概念与数据恢复
    ubuntu个人初始配置记录
    H.264学习笔记6——指数哥伦布编码
    H.264学习笔记5——熵编码之CAVLC
    C/C++语言学习——内存分配管理
    H.264学习笔记4——变换量化
  • 原文地址:https://www.cnblogs.com/hualou/p/12163941.html
Copyright © 2011-2022 走看看