• 什么时候创建组合索引?最左匹配原则?


    文章出处 http://www.cppcns.com/shujuku/mysql/254483.html

    前言

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

    什么时候创建组合索引?

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

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

      (1)减少开销:假如对col1、col2、col3创建组合索引,相当于创建了(col1)、(col1,col2)、(col1,col2,col3)3个索引
      覆盖索引:假如查询SELECT col1, col2, col3 FROM 表名,由于查询的字段存在索引页中,那么可以从索引中直接获取,而不需要回表查询

      (2)效率高:对col1、col2、col3三列分别创建索引,MySQL只会选择辨识度高的一列作为索引。假设有100w的数据,一个索引筛选出10%的数据,那么可以筛选出10w的数据;对于组合索引而言,可以筛选出100w*10%*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 <5000000do
    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';

     

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

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

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

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

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

    1. EXPLAIN SELECT * FROM student WHERE name ='defghijk' AND age =8;

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

    1. EXPLAIN SELECT * FROM student WHERE name ='defghijk' AND id =2;
    2.  
    3. EXPLAIN SELECT * FROM student WHERE age =8 AND id =2;
    4.  
    5. EXPLAIN SELECT * FROM student WHERE name ='defghijk'and age =8 AND id =2;

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

    总结

      如上测试,可以看到只要查询条件的列中包含组合索引最左边的那一列,不管该列在查询条件中的位置,都会使用索引进行查询。

       

     
  • 相关阅读:
    Django基础(一)_URLconf、Views、template、ORM
    MySQL数据库(8)_MySQL数据库总结
    MySQL数据库(6)_用户操作与权限管理、视图、存储过程、触发器、基本函数
    前端基础之jquery_mouse相关操作与不同
    前端基础之jquery
    前端基础之JavaScript_(5)_DOM对象总结
    前端基础之JavaScript_(4)_js的作用域
    前端基础之JavaScript_(3)_DOM对象
    MSB与LSB Big Endian Little Endian
    samba配置
  • 原文地址:https://www.cnblogs.com/AbnerLc/p/11924933.html
Copyright © 2020-2023  润新知