今日客户现场出现一个查询SQL异常慢的情况。
用时分钟级别。
SELECT * FROM (SELECT a1.*,rownum rn FROM (SELECT openOrder2017.exchId, ............ openOrder2017.internalbizmark, customer.typeIdList FROM openOrder2017,customer WHERE openOrder2017.custId = customer.custId AND openOrder2017.orderTime >= 20170810000000 AND openOrder2017.orderTime <= 20170811235959 AND openOrder2017.branchId IN ('001100','001101') AND openOrder2017.acctId IN ('##########') AND openOrder2017.optLevel IN ('A0') AND openOrder2017.custType IN ('A2','A9','A1','A4','A3') ORDER BY orderTime,serialNum) a1 WHERE rownum <= 100) a2 WHERE rn >= 1;
其中:
openOrder2017表数据量360万条;
customer表数据量76条;
执行计划利用上了ACCTID索引,但是有大量的NESTED LOOPS,导致异常高的逻辑读。
将SQL中的AND openOrder2017.acctId IN ('##########')条件取消,SQL查询速度反而变快了,但是走的是全表扫描方式。
突然醒悟,这是两个数据体量差距异常大的表,有严重的数据倾斜。通过openOrder2017.acctId索引访问,反而代价很大,择全表扫描的效率比选择索引要更高。
改造为: FROM openOrder2017 left join customer on openOrder2017.custId = customer.custId WHERE openOrder2017.orderTime >= 20170810000000 AND openOrder2017.orderTime <= 20170811235959
执行计划虽然走了全表扫描,但是执行效率大幅提升了。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|