-
问题现象
突然收到业务部门的联系,说一个页面打开一直转,然后就503超时。 -
问题分析
收到消息第一时间拿到生产日志进行分析,一看日志发现接口最后响应成功,不过从收到前端发送请求到接口响应花了两三分钟时间。初步判断某个地方执行时间花费时间久,可能一下的情况:- 循环
- 慢sql
- 外部接口响应慢
接口处理没有循环,而外部接口日志处理都正常,最终确认由一下慢sql导致的响应超时,数据库使用的是Oracle:
select col
from t1 left join t2 on t1.id = t2.id
where t1.id = 'xx' or t2.id1 = 'xx';
- 问题改造及优化
其中t1表的id字段已经创建索引,id1字段并没有创建索引,而整张表的数据量已经千万级别甚至达到亿级,此时id1作为条件查询必然出现全表扫描,id字段索引失效。假设已经在id1字段创建了索引,在分析此sql,理论上只会走一个索引,但是Oracle的执行计划跟使用UNION ALL相同,两个字段都是用了索引
select col
from t1 left join t2 on t1.id = t2.id
where t1.id = 'xx'
UNION ALL
select col
from t1 left join t2 on t1.id = t2.id
where t2.id1 = 'xx';
所以我认为Oracle进行了优化。
- 使用说明
对于or条件查询谨慎使用,如果没有字段没有创建索引可能会导致全表扫描,如果or两边查询字段相同尽量使用in优化,如果两边不是同一个字段且都创建了索引,则使用union进行联合查询。