注册
一个普通查询变慢的优化过程
专栏/技术分享/ 文章详情 /

一个普通查询变慢的优化过程

BruceCD 2025/11/21 351 0 0
摘要

概述

某客户遇到一个很奇怪的问题,测试环境下和生成环境下同一个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

排查过程

首先比较下它们的执行计划,可以看到基本上一样(生产环境版本略高一些,所以有些小差异):
图片.png

再比较两个环境下的表结构发现也是一样的,检查它们的表结构,也是一模一样的。

查看生产环境下这个语句的ET信息如下:

图片.png

可以看到BLKUP2操作符的耗时居然达到了753毫秒,这种情况很不正常,然后检查下它的内存相关参数,感觉可能是IO的问题,再检查生产环境的BUFFER参数,发现只有5G,相比于机器内存(128G)不匹配。经过沟通得知此集群没有执行过优化脚本生成的调优参数语句,所以都是默认值。此时我们将参数都调优配置了一下,重启集群,再去验证前面的SQL,已经恢复正常执行不超过1ms,查看ET信息如下:

图片.png

总结

在排查过程中,还出现了一个小插曲,比如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就能对比出来执行过程不正常,后续需要深入研究下各个参数的影响以及对应的表现。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服