某客户遇到一个很奇怪的问题,测试环境下和生成环境下同一个SQL语句执行,结果相同,但是耗时相差几百倍,测试环境执行只要几毫秒,生产环境下却需要1千多毫秒。
select
*
from
MASTER_DATA.OFFICIAL_ORGS oo
left join MASTER_DATA.OFFICIAL_ORG_USER oou on oo.ORG_ID = oou.ORG_ID
where
oou.USER_CODE = '123456'
and oo.TENANT_ID = 'default'
and oo.IS_DELETED = '0'
order by oou.IS_PRIMARY desc, oou.DISPLAY_ORDER asc, oou.CREATED_TIME desc
首先比较下它们的执行计划,可以看到基本上一样(生产环境版本略高一些,所以有些小差异):
再比较两个环境下的表结构发现也是一样的,检查它们的表结构,也是一模一样的。
查看生产环境下这个语句的ET信息如下:
可以看到BLKUP2操作符的耗时居然达到了753毫秒,这种情况很不正常,然后检查下它的内存相关参数,感觉可能是IO的问题,再检查生产环境的BUFFER参数,发现只有5G,相比于机器内存(128G)不匹配。经过沟通得知此集群没有执行过优化脚本生成的调优参数语句,所以都是默认值。此时我们将参数都调优配置了一下,重启集群,再去验证前面的SQL,已经恢复正常执行不超过1ms,查看ET信息如下:
在排查过程中,还出现了一个小插曲,比如ET信息会偶发看不到,这是因为ET信息都是存储在内存缓存中的,而这部分缓存是有大小限制的,在开启了全局的ENABLE_MONITOR和MONITOR_SQL_EXEC后,当SQL执行非常频繁时,新执行的SQL的ET信息就会把之前执行过的SQL的ET信息覆盖掉导致查不到,所以需要先关闭全局的MONITOR_SQL_EXEC开关,然后开启会话级别的MONITOR_SQL_EXEC,这样就不会被很快得覆盖掉:
-- 关闭全局的MONITOR_SQL_EXEC
SP_SET_PARA_VALUE(1, 'MONITOR_SQL_EXEC',0);
-- 会话中设置MONITOR_SQL_EXEC值
SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC',1);
对于此次的慢查询优化经验,主要还是在于了解到了内存参数对于查询的影响,在未配置优化参数的情况下,一个很普通的联表查询在使用到索引的情况下也会非常慢,从ET信息中每个操作符的N_ENTER就能对比出来执行过程不正常,后续需要深入研究下各个参数的影响以及对应的表现。
文章
阅读量
获赞
