问题现象
在客户的运营系统中,当客户执行某个条件的订单查询时,接口响应超时,同时服务器的cpu利用率高达100%
![](https://img.haomeiwen.com/i13084796/5a04eb2a8a93226c.png)
问题排查
问题sql
SELECT
count( 0 )
FROM
orders
WHERE
1 = 1
AND IS_PAYED = 2
AND ORDER_TYPE != 3
AND `ORDER_TYPE` = 1
AND `ORDER_NUM` IN ( SELECT ORDER_NUM FROM orders_bill WHERE OPERATION_ID = 37 );
备注
上述俩种表中的数据量分别是:4万 和七万
执行explain
![](https://img.haomeiwen.com/i13084796/fcb772dcc2c4dade.png)
关于Block Nested-Loop
![](https://img.haomeiwen.com/i13084796/e15b089543d9387f.png)
![](https://img.haomeiwen.com/i13084796/a095f855d4edb73c.png)
![](https://img.haomeiwen.com/i13084796/15b845db241f8601.png)
问题修复
修复方案一
对order_bill表建立索引,避免全表扫描
![](https://img.haomeiwen.com/i13084796/b935255ac9ecad64.png)
处理后的执行计划
![](https://img.haomeiwen.com/i13084796/6d1da4f91ad8aa48.png)
可以看到此时,已经使用了索引,同时mysql也不再使用Block Nested Loop
进一步优化
对order表也建立索引
![](https://img.haomeiwen.com/i13084796/586ad4561cf0341e.png)
执行计划
![](https://img.haomeiwen.com/i13084796/4fbc53be04d9f299.png)
可以看到,此时对order表的查询也不再走全面扫描,而是使用了索引
最终优化
sql如下
EXPLAIN SELECT
count( 0 )
FROM
orders o
INNER JOIN ( SELECT DISTINCT ORDER_NUM FROM orders_bill WHERE OPERATION_ID = 37 ) ob ON o.ORDER_NUM = ob.ORDER_NUM
WHERE
1 = 1
AND o.IS_PAYED = 2
AND o.ORDER_TYPE != 3
AND o.`ORDER_TYPE` = 1
执行计划
![](https://img.haomeiwen.com/i13084796/824120873098ab68.png)
最终优化后的查询结果
![](https://img.haomeiwen.com/i13084796/76abd1da01c92d78.png)
网友评论