• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    MySql范围查找时索引不生效问题的原因分析

    1 问题描述

    本文对建立好的复合索引进行排序,并取记录中非索引字段,发现索引不生效,例如,有如下表,DDL语句为:

    CREATE TABLE `employees` (
     `emp_no` int(11) NOT NULL,
     `birth_date` date NOT NULL,
     `first_name` varchar(14) NOT NULL,
     `last_name` varchar(16) NOT NULL,
     `gender` enum('M','F') NOT NULL,
     `hire_date` date NOT NULL,
     `age` int(11) NOT NULL,
     PRIMARY KEY (`emp_no`),
     KEY `unique_birth_name` (`first_name`,`last_name`) USING BTREE
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    复合索引为unique_birth_name (first_name,last_name) 。使用以下语句:

    EXPLAIN SELECT
     gender
    FROM
     employees
    ORDER BY
     first_name,
     last_name

    根据上图:type:all 及 Extra:Using filesort 可得,索引没有生效。

    继续进行试验,对查询语句进一步改写,加上一个范围查找:

    EXPLAIN SELECT
     gender
    FROM
     employees
    WHERE first_name > 'Leah'
    ORDER BY
     first_name,
     last_name

    执行计划显示如下图:

     

    这里发现结果和第一次sql分析无异。继续试验。

    改写sql语句:

    EXPLAIN SELECT
     gender
    FROM
     employees
    WHERE first_name > 'Tzvetan'
    ORDER BY
     first_name,
     last_name

     

    此时,令人惊讶的是,索引生效了。

    2 问题分析

    此时,我们做一个大胆的猜测:

    第一次进行sql分析时,因为第一次order by 后,得到的还是全表数据,如果根据复合索引中携带的主键查找每一个gender进行拼接,自然很费资源和时间,mysql不会做如此蠢的事。不如直接进行全表扫描,把扫描到的每条数据和order by得到的临时数据进行拼接,从而得到需要的数据。

    为了验证上述想法的正确性,我们对三次sql进行分析。

    第一次sql根据复合索引得到的数据量为:300024,为全表数据

    SELECT
     COUNT(first_name)
    FROM
     employees
    ORDER BY
     first_name,
     last_name

    第二次改写的sql根据复合索引得到的数据量为:159149 , 为全表数据量的1/2。

    SELECT
     COUNT(first_name)
    FROM
     employees
    WHERE first_name > 'Leah'
    ORDER BY
     first_name,
     last_name

     

    第三次改写的sql根据复合索引得到的数据量为:36731, 为全表数据量的1/10。

    SELECT
      COUNT(first_name)
    FROM
      employees
    WHERE first_name > 'Tzvetan'
    ORDER BY
      first_name,
      last_name

    通过对比发现,第二次改写的sql根据复合索引得到的数据量是全表数据量的1/2。此时还没有达到mysql使用索引进行二次查找的量级。第三次改写的sql根据复合索引得到的数据量是全表数据量的1/10,达到了mysql使用索引进行二次查找的量级,于是从执行计划上可以看到,第三次改写sql是走了索引的。

    3 总结

    mysql 是否根据首次索引条件查询出的主键进行二次查找,也是要看查询出来的数据量级,如果数据量接近全表数据量的话,就会进行全表扫描,否则根据第一次查询出来的主键进行二次查询。

    到此这篇关于MySql范围查找时索引不生效问题原因分析的文章就介绍到这了,更多相关MySql范围查找索引不生效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • MySQL用B+树作为索引结构有什么好处
    • 为什么MySQL数据库索引选择使用B+树?
    • MySQL 全文索引的原理与缺陷
    • Mysql 5.6 "隐式转换"导致的索引失效和数据不准确的问题
    • MySQL索引失效的几种情况详析
    • MySQL8.0中的降序索引
    • MySQL 8.0 之索引跳跃扫描(Index Skip Scan)
    • mysql性能优化之索引优化
    • mysql 使用B+树索引有哪些优势
    上一篇:Mysql exists用法小结
    下一篇:Mysql事务中Update是否会锁表?
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    MySql范围查找时索引不生效问题的原因分析 MySql,范围,查,找时,索引,