首页 > 编程知识 正文

什么情况下索引失效,sql什么情况下不会使用索引

时间:2023-05-04 01:48:27 阅读:159603 作者:3591

摘要索引条件下的推送优化(indexconditionpushdown(ICP ) )是MySQL5.6添加的,用于优化数据查询。

如果在不使用索引的情况下推送优化,存储引擎会从索引中检索数据并返回到MySQL服务器,服务器将确定数据是否满足条件。 通过优化当使用索引条件下推优化时,如果存在某些被索引的列的判断条件时,MySQL服务器将这一部分判断条件传递给存储引擎,然后由存储引擎通过判断索引是否符合MySQL服务器传递的条件,只有当索引符合条件时才会将数据检索出来返回给MySQL服务器索引,可以减少存储引擎查询基础表的次数,以及MySQL服务器从存储引擎接收数据的次数。 我在网上搜索的很多相关文章都把索引连接器推式下载称为索引下推优化。 我认为这种优化技术的重要操作是通过将索引相关条件从MySQL服务器下载到存储引擎来减少io次数。 由于从MySQL服务器向下传递到存储引擎的是与索引列相关的查询条件,因此还是按索引条件推送优化更容易理解。

适用条件需要全表扫描时。 例如range、ref、eq_ref、ref_or_null。 适用于查询InnoDB和MyISAM引擎。 5.6版不应用分区表查询,5.7版及更高版本可用于分区表查询。 InnDB引擎仅应用于辅助索引。 减少按索引条件推送的主要目的IO次数是没有意义的,因为InnDB的聚簇索引将整行数据读取到InnDB的缓冲区中。 数据已经在内存中了,不需要读取。 不能下拉引用子查询的条件。 不能推送调用存储过程的条件。 存储引擎无法调用位于MySQL服务器上的存储过程。 触发条件不能按下。 既然工作流程是优化的,我们要明确优化了什么,就要知道本来是怎么工作的,所以分两部分来描述工作流程。

不使用索引条件下推优化时的查询过程

要获取下一行,请先读取索引信息,然后根据索引读取整行的数据。

然后,在where条件下判断当前数据是否满足条件,是否满足返回数据。

使用索引条件下推优化时的查询过程

获取下一行的索引信息。

检查索引中存储的列信息是否满足索引条件,如果匹配,则读取整行的数据,否则跳过读取下一行。

利用剩下的判断条件,判断该行的数据是否满足要求,满足要求返回数据。

EXPLAN分析

使用explan进行分析时,如果按索引推送,则Extra不是http://www.Sina.com/using索引。 根据索引条件推送查询的数据不一定符合要求,因此必须根据其他查询条件进行确定。

Using index condition

步骤说明::MySQL Server发出读取数据的命令。 它通过执行程序执行与以下内容类似的代码段,并通过函数指针和handle接口调用存储引擎的索引读取或所有表读取: 在此进行索引读取。

if(in_first_read ) {in_first_read=false; error=(qep _ ta B- read _ first _ record ) ) qep_tab; //设置适当的读取函数(elseerror=info-read_record ) (info ),例如设置索引读取函数/所有表扫描函数; ) )进入存储引擎,读取索引树,在索引树中查找,从表记录中读取符合条件的(查找结果为红色的) (通常有IO ),从存储引擎中读取标记的其中,不仅通过索引慢行进行索引读取,而且通常是存储器中的快速。 () ),再进一步),通常有IO。

)从存储引擎中找到的多个元组被返回到MySQL Server。 MySQL Server在中得到了很多元组。

-? 根据WHERE子句的条件过滤~,得到满足条件的组。 请注意,在MySQL Server层获得大量元组后进行过滤。 最终得到的是满足少量条件的元组。

图一:不使用ICP技术(过程使用数字符号标示,如等)

流程解释():MySQL Server发出读取数据的命令。 过程与图相同。

) )进入存储引擎,读取索引树,在索引树中查找,从表记录中读取符合已推送条件的(查找结果为红色的) (一般有IO )、存储

图二:使用ICP技术(过程使用数字符号标示,如等)由此,与没有ICP的方式相比,IO量减少。

)将从存储引擎中找到的少量元组返回给MySQL Server。 MySQL Server在中得到少数元组。 因此,比较图表中没有ICP的方式被返回到MySQL Server

层的即是少量的、符合条件的元组。
另外,图中的部件层次关系,不再进行解释。

示例

假设有一张people表,包含字段name、address、first_name
索引为(name,address,first_name)
然后我们执行下面的查询

SELECT * FROM person WHERE `name` = "1" AND `address` LIKE "%222" and first_name LIKE "%222";

如果不使用索引条件下推优化的话,MySQL只能根据索引查询出name=1的所有行,然后再依次比较是否符合全部条件。

当使用了索引条件下推优化技术后,可以通过索引中存储的数据判断当前索引对应的数据是否符合条件,只有符合条件的数据才将整行数据查询出来。查看执行计划时发现extra一栏中有Using index condition信息,说明使用了索引下推。

配置

索引下推优化是默认开启的。可以通过下面的脚本控制开关

SET optimizer_switch = 'index_condition_pushdown=off'; SET optimizer_switch = 'index_condition_pushdown=on'; 思考

索引下推优化技术其实就是充分利用了索引中的数据,尽量在查询出整行数据之前过滤掉无效的数据。

由于需要存储引擎将索引中的数据与条件进行判断,所以这个技术是基于存储引擎的,只有特定引擎可以使用。并且判断条件需要是在存储引擎这个层面可以进行的操作才可以,比如调用存储过程的条件就不可以,因为存储引擎没有调用存储过程的能力。

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。