mysql 慢sql之index_merge

收到超时报警:Receive data timeout or error!timeout:5700ms。。。。。

看了下,实际执行花了20多S,超出dsf框架的超时时间,不等返回数据,直接就抛异常了。

*********************************************************************************************

看下对应的慢sql.

select count(1) from table where 

key_part1=const1 AND key_part2=const2 ... AND key_partN=constN

线上从库执行了下,得却是慢,排除了网络抖动原因。

explain看下执行计划。type是index_merge,posssible_keys是3个独立索引。

说一下mySQL执行的大概流程:MySQL解析器先进性解析,进行统计信息收集,然后优化器进行选择最优的执行计划,然后发送给MySQL 进行执行,最后返回结果接客户端。所以这里对and 条件的先后没有关系。

慢就是这个index_merge的原因。

补充下index_merge对应的常见业务场景:

1) 对 OR 取并集 

比如:select count(1) from table where key1 = a or key2= b

key1,key2都有对应的索引。所以结果就是执行计划会采用 union merge 算法。

2) 对 and 取交集

就是我一开始的例子,当where条件中含有索引列的and操作时,执行计划会采用intersect 并集操作。

看下执行计划的extra字段:Using intersect(idx_key1,idx_key2); Using where

3) 对 AND 和 OR 的组合取并集。

找个例子:

SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;
sort-union合并算法和union合并算法的不同点,在于返回结果之前是否排序,The difference between the sort-union algorithm and the union algorithm is that the sort-union algorithm must first fetch row IDs for all rows and sort them before returning any rows.

对于报警的慢SQL,多个条件而MySQL没有使用最优的执行计划。对于这种局限:

可以使用复合索引。

我们的业务场景是后台根据条件查询,偶发的。所以暂不实施。

可以对比下。使用时间索引优化的结果 FORCE INDEX(idx_service_time)

mysql 慢sql之index_merge

可见单使用时间索引,而不是index merge会快很多。当然这表数据量很大近千万也是影响因素。