问题背景
测试环境发现有sql 时不时查询达到3s 多,该条sql查询结果只有1条,并且走了索引,拿出sql到客户端执行又很快,毫秒级别,相差达到上百倍,条件是相同的,sql也是带传参的。
疑问点:
1、查询走索引为什么还要到3秒多。
2、为什么有时快毫秒就查询出结果,有时慢到3秒多。
检查结果
1、在磁盘性能较差并且需要物理读的页相对多的时候,会出现执行时间较久的情况,sql执行耗时时间在io wait。
2、表数据被清出缓存后,首次查询会出现物理读,如IO较差或者不稳定,会有耗时较久的情况,再次查询,数据已经在缓存,没物理读,执行时间很快。
检查过程
1、首次跑该条语句,检查sql 的执行计划和autotrace
语句为单表查询,
select xxxx,xxx,xxx,xxx from xxxx_ARCH where xxxx_NO = 'xxxxxxxxxx48' AND (xxxxxAG = 'N' OR xxxxxAG IS NULL) AND xxxxxUS = '3' ORDER BY xxxxxNO ASC
上图可看到耗时1秒多,主要耗时在io wait,语句需要65物理读。
2、再次跑该条sql,执行计划一样,耗时毫秒级别,已经没有物理读。如下图
3、模拟首次跑的时候有另外的全扫sql在执行
重启数据库,让语句需要物理读,在另外窗口执行全扫的sql,加大IO 负担,查看结果。客户端开两个连接。分别执行全扫sql,然后执行语句耗时3s多,耗时在io wait.
观察磁盘情况
4、索引扫描为什么要到65物理读
检查表结构和索引,表是32个hash分区表,分区字段不是where条件字段,
走索引的条件xxxx_NO 为局部索引。
5、xxxx_NO 改成全局索引
第一次跑计划如下,此时只需要4 物理读,90多ms,大大提升效率。
6、在别的环境模拟该查询
其他全扫sql在执行的情况下,33物理读在带,耗时20多ms。
总结
磁盘IO较差或者被其他地方占用IO的情况下,会导致sql执行时间较长或波动大,应加强监控,IO占用多的地方及时处理。
文章
阅读量
获赞