加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

十年DBA老兵:警惕,重Java轻SQL乃性能大忌

发布时间:2017-09-19 15:43:05 所属栏目:建站 来源:DBAplus社群
导读:副标题#e# 作者:黄浩 简介:从业十年,始终专注于 SQL。十年一剑,十年磨砺。3 年通信行业,写就近 3 万条 SQL;5 年制造行业,遨游在 ETL 的浪潮;2 年性能优化,厚积薄发自成一家。 注:《SQL性能优化与批判》是黄浩老师的系列新作,他将从过往在项目技

战战兢兢,如履薄冰

没有任何的注释,代码中的表呀,字段呀什么的,我一个也不认识,唯一亲切的就是 select from where join group 这些被标绿的 SQL 关键字。

“这个 SQL 有什么性能症状?”

“跑起来很慢。”

“慢到什么程度?”

“大概需要半个多小时才能跑完。”

“数据量很大吗?”

“可能吧,我还没有执行过,只是听开发人员这么说的。”

看来我不能从这位同事这里得到更多有价值的信息了。

按下 F5 查看执行计划:

十年DBA老兵:警惕,重Java轻SQL乃性能大忌

执行计划中,表访问方式基本上都是 index scan,而且也并无大成本的操作。奇怪了,问题处在哪里呢?我又回到 SQL 窗口,按下 F8,果然只见时间过,不见数据出来。

在长期与 SQL 相伴的日子里,我养成了一个习惯,喜欢在边看着 Oracle 执行,一边分析代码,大有“我忙着分析,你也别闲着偷懒”的“小人嘴脸”。

这个 SQL 有两个部分,第一部分是用 with 封装了一个结果集,第二部分是对第一部分的结果集进行 group by 处理。根据过往经验,我将 SQL 复制到了另一个 SQL 窗口,选中 with 子句单独执行,秒出呀。

排除了子查询的性能嫌疑,那么很显然问题是出在第二部分的 SQL。第二部分 SQL 包含了 group by,难道是 group by 产生了性能问题。要知道,group by 等聚合操作的性能对数据量是极其敏感的。难道是 with 子查询的数据量非常大?

我赶紧 count 了第一部分 SQL 的结果集,显示不到 20 万数据。那就不应该呀,20 万数据做 group by 也不至于慢成“蜗牛”呀。

继续分析第二部分 SQL 代码,在 select 子句中,惊现 wm_concat 函数。此时,我还是有些小激动的,因为在之前也遇到过由于 wm_concat 引发的性能问题。为了验证判断,我将 wm_concat 注释掉,按F8 运行,果然飞快,不到 1s 就出结果。

至此,通过排除法,病因是找到了:由 wm_conca t引发了性能问题。

顺藤摸瓜,顺手牵羊

原因已经找到,那么对症又该如何下药呢?显然,从 SQL 功能上,wm_concat 是必须的,我也尝试过用 listagg 来替代 wm_concat,但是会因超过 4000 字符而报错。

其实 wm_concat 函数之所以慢,就是因为以 task_name 为维度需要拼凑的数据量太大导致的。难道就无解了吗?

我转念一想,为什么要用 wm_concat 函数?应用程序在拿到这个字段后做什么用呢?在前端页面显示吗?

这种显示是没有多大意义的,因为 wm_concat 的结果可能非常大,根本就显示不了。既然显示不完整,那么为什么又要从 DB 中获取完整的内容呢?

带着这些疑惑,我与 SQL 开发人员进行了沟通,原来,应用程序拿到这个 SQL 的数据后,并不是在前端页面展现,而是在应用程序中继续加工处理,在经过若干复杂的逻辑处理后,以另一种形式在页面展现。

此时,多年的从业经验告诉我:既然可以用 Java 来实现的业务逻辑,那么肯定也能在 DB 中通过 SQL 来实现,这样就可以避开 wm_concat 函数。

于是我决心深入了解业务功能,希望能从业务方案上有所突破。这样就形成了一个初步的工作计划:了解整体业务功能及逻辑-->了解应用程序处理逻辑-->改写 SQL 语句-->功能性测试-->性能轮回调整。

在大约两个小时的一对一讲解后,我基本上掌握了整体业务功能及逻辑、应用技术架构及处理逻辑。

这个其实是一个报表展现功能,是按区域、里程碑展现两个相邻里程碑之间的时间间隔,包括计划间隔时间与实际间隔天数(平均)。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读