zoukankan      html  css  js  c++  java
  • MySQL优化器不使用索引的情况

    优化器选择不适用索引的情况

    有时候,有乎其并没有选择索引而去查找数据,而是通过扫描聚集索引,也就是直接进行全表的扫描来得到数据。这种情况多发生于范围查找、JOIN链接操作等情况。例如

    SELECT * FROM orderdetails WHERE orderid>10000 and orderid<102000;

    通过SHOW INDEX FROM orderdetails可以看到

    可以看到orderdetails有(orderID,ProductID)的联合主键。此外还有对于列OrderID的单个索引。上述SQL显然是可以通过扫描orderID上的索引进行数据查询的,但通过EXPLAIN发现优化器并没有按照OrderID来查找数据

    在possable_keys中看到查询可以使用primary、OrderID,OrdersOrder_Details这三个索引。但是在最后的索引中,优化器选择了primary聚集索引。也就是表扫描table scan,而非OrderID辅助索引扫描index scan

    原因分析:用户要选取的数据是整行信息,而OrderID索引不能覆盖到我们要查询的信息。因此在OrderID索引查到指定数据后,还需要一次书签访问来查找整行的数据信息。虽然OrderID索引中数据是顺序存放的。但再一次进行书签查找的数据则是无序的,因此变为了磁盘上的离散读操作。如果要求访问的数据流很小,则优化器还是会选择辅助索引,但是当访问的数据占整个表中数据的蛮大一部分时(一般为20%左右),优化器会通过聚集索引来查找数据,因为之前已经提到过。顺序读要远远快于离散读

    因此对于不能进行索引覆盖的情况,优化器选择辅助索引的情况是,通过辅助索引查找的数量是少量的,这是由当前传统机械硬盘的特性决定的。即利用顺序读来替换随机读的查找。若用户使用的是固态硬盘,随机读操作非常快,同事有足够的自信来确认使用辅助索引可以带来更好的性能,那么可以使用关键字FORCE INDEX来强制某个索引

     SELECT * FROM orderdetails  FROCE INDEX(OrderID) WHERE orderid>10000 and orderid<102000;
  • 相关阅读:
    log4j2 配置详解
    MANIFEST.MF文件详解
    assembly.xml
    firewall 和 iptables 常用命令
    Spring boot 使用 configuration 获取的属性为 null
    使用 maven-assembly-plugin 打包项目
    使用 Maven 插件将 class(字节码文件),resource(资源文件),lib(依赖的jar包)分开打包
    HttpClient 传输文件的两种方式
    IDEA中读取 resource目录下文件
    3.2、Android Studio在物理设备中运行APP
  • 原文地址:https://www.cnblogs.com/olinux/p/5146620.html
Copyright © 2011-2022 走看看