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