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;
时间: 2024-10-13 12:36:54

MySQL优化器不使用索引的情况的相关文章

MySQL优化器 limit影响的case

测试的用例中,因为limit的大小不同,而产生了完全不同的执行计划: 1. 测试case: create table t1 ( f1 int(11) not null, f2 int(11) not null, f3 int(11) not null, f4 tinyint(1) not null, primary key (f1), unique key (f2, f3), key (f4) ) engine=innodb; insert into t1 values (1,1,991,1),

MySQL order by后对其他索引的干扰,导致优化器走错索引

MySQL version:5.5.36 [email protected] 5.5.36-log xxx 10:19:54>show index from FD_FINANCE_ACC_HIS;+--------------------+------------+------------------------+--------------+--------------+-----------+-------------+----------+--------+------+---------

空表情况下,优化器不用预定索引一次现象

错误描述:表行如下,表中数据为空,进行执行分析时候,发现优化器没有按照预定那样走第二条索引,很奇怪 mysql> show create table answer_survey_info\G *************************** 1. row *************************** Table: answer_survey_info Create Table: CREATE TABLE `answer_survey_info` ( `answerId` bigi

结合mysql查询优化器对联合索引的探讨

无陈述,直接开讲: babysitter_account表中的联合索引如下(开发小伙伴们自建的联合索引.您发现不妥了吗?): KEY `flag` (`flag`,`user_id`,`account_id`) 过去认为: 1.SELECT account_id,weibo_id,weibo_type FROM babysitter_account WHERE user_id BETWEEN 100 and 10000 AND flag=0; 2.SELECT account_id,weibo_

数据库 mysql 优化器原理

MySQL查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行. 你的最终目标是提交SELECT语句查找数据行,而不是排除数据行.优化器试图排除数据行的原因在于它排除数据行的速度越快,那么找到与条件匹配的数据行也就越快. 如何 更好的 利用索引: 1:尽量比较数据类型相同的数据列.当你在比较操作中使用索引数据列的时候,请使用数据类型相同的列.相同的数据类型比不同类型的性能要高一些. 例如,INT与BIGINT是不同的.CHAR(10)被认为是C

Mysql优化之创建高性能索引(一)

1.索引基础 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.但是不恰当的索引随着数据量的增加,也会使整个数据库的性能下降. 举个例子: select a from b where id = 5; 如果在id上建立索引,则Mysql会使用该索引找到id为5的行,也就是说,Mysql现在索引按值进行查找,然后返回所有包含该值的数据行.索引也可以包含一列或者多列,列的顺序也十分重要,因为Mysql只能高效地使用索引的最左前缀列. 索引优化应该是查询性能优化最有效

mysql优化实战(explain &amp;&amp; 索引)

实验环境: 1.sql工具:Navicat 2.sql数据库,使用openstack数据库作为示例 一.mysql索引查询 show index from instances 结果字段解释: Table:数据库表名 Non_unique:索引不能包括重复词,则为0.可以,则为1. Key_name:索引的名称. 索引中的列序列号,从1开始. 列名称 列以什么方式存储在索引中.在MySQL中,有值'A'(升序)或NULL(无分类). 索引中唯一值的数目的估计值.通过运行ANALYZE TABLE或

MySQL优化器功能开关optimizer_switch

MySQL 8.0新增特性 use_invisible_indexes:是否使用不可见索引,MySQL 8.0新增可以创建invisible索引,这一开关控制优化器是否使用invisible索引,on表示考虑使用. MySQL 5.7新增 derived_merge:派生表合并,类似Oracle的视图合并,当派生SQL中存在以下操作是无法展开UNION .GROUP .DISTINCT.LIMIT及聚合操作 duplicateweedout:是否使用使用临时表对semi-join产生的结果集去重

[MySQL优化案例]系列 — 典型性索引引发CPU负载飙升问题

收到一个mysql服务器负载告警,上去一看,load average都飙到280多了,用top一看,CPU跑到了336%,不过IO和内存的负载并不高,根据经验,应该又是一起索引引起的惨案了. 看下processlist以及slow query情况,发现有一个SQL经常出现,执行计划中的扫描记录数看着还可以,单次执行耗时为0.07s,还不算太大.乍一看,可能不是它引发的,但出现频率实在太高,而且执行计划看起来也不够完美: mysql> explain SELECT count(1) FROM a