今天查看MySQL慢查询日志,查看一个四表关联的SQL操作,耗时1006s。这次也是基于基于子查询的思路,对上表进行优化。使时间复杂度降到n^2级别。但优化之后时间反而是原来的三倍多。
原SQL语句:
explain select distinct b.businessId from
gte_order o,
gte_jy_contract c,
flow_ru_participant tp,
flow_ru_business b
where b.businessId = o.businessId
and o.businessId=c.businessId
and b.businessId = tp.businessId
and o.cityCode = 120000
and tp.status = 0
and o.status in
(
-1,6,7
)
order by o.createTime;
耗时1s多,
优化后的语句:
#3 s 334 ms
desc select distinct tempB.businessId #distinct导致temportory
from (select o.businessId,o.createTime
from gte_order o,gte_jy_contract c
where o.businessId = c.businessId and o.status in (-1,6,7) and o.cityCode = 120000) as tempA,(select b.businessId
from flow_ru_participant p,flow_ru_business b
where b.businessId = p.businessId and p.status = 0) as tempB
where tempA.businessId = tempB.businessId
order by tempA.createTime;#filesort
耗时3s多。
查看其执行计划后可知:
修改后的执行计划:
由于索引的存在:原SQL只会遍历自己的索引(涉及的行为72426),然后一次去查询另外三表的索引(涉及的行为1,1,3),所以其时间复杂度为O(n)级别。
然而子查询的方式,首先两表直接查询时间复杂度为O(n),两个表衍生出来的临时表之间再进行查询,时间复杂度为O(n),索引的存在让时间复杂度降到O(n)。此时总时间复杂度大致为3*O(n),符合时间查询时间的结果。
总结:
对于SQL查询来说,索引是其效率优化的最主要方式,但由于索引其本身的缺点及其局限性,数据表的索引是有限的,功能也是有限的。所以需要辅助于其它方式。但是书写SQL语句时,应首先考虑索引的情况。
如:如何建索引,如何用索引,没有索引时如何优化。
另:关于SQL超时问题,与SQL无关,猜测是网络的原因。