首页 > 数据库 > Oracle > wm_concat和listagg
|
接到客户通知,我首先远程登录客户系统查看。 1、 检查应用所在主机负载—检查正常 2、 检查ORACLE所在主机负载情况,检查发现基本都是ORACLE进程导致的资源消耗
3、 接着我查看数据库会话情况如下图,发现运行的SQL消耗大量临时段。
|
|||||
|
4、 接着查看涉及的SQL 执行计划,均正常。 5、 前面发现占用大量的临时段,让我觉得不可思议,理论上:只有存在如下情况才会出现临时段的大量使用 1、 HASH JOIN 内存不够借助TEMP表空间 2、SORT 内存不够借助TEMP表空间 3、临时对象占用temp表空间 4、LOB 对象占用TEMP表空间 2、 从上面监控可以发现主要消耗临时段的对象类型是LOB_DATA 3、 我去查询了SQL 相关的表对象,未发现这些表里面定义了LOB相关的字段。
4、 接着排除法:排除语句里面涉及可能使用TEMP 的地方:发现如下位置 当我去掉这里的时候,该SQL在没有使用到TEMP。 初步定位是由于VM_CONCAT导致 6、 在MOS上面查询到如下关于wm_concat的说明
从上面可以发现,wm_concat函数官方是不推荐使用的,该函数在数据库版本是10.2.0.4,11.1.0.7,11.2.0.1中是返回的VARCHAR2类型 该函数在10.2.0.5和11.2.0.2+以上返回的是CLOB 类型 从上面可以解释为什么监控发现有大量的临时表空间消耗。同时也说明了使用CLOB字段的wm_concat函数性能上很低下。 分析到这里基本定位问题是由于数据库升级后,函数返回值发生变化导致了查询效率低下,同时也导致了大量的临时段被使用。
7、 如何替换wm_concat行专列函数 1、 ORACLE建议使用自定义函数。 2、 我个人推荐使用LISTAGG(11R2引入的新函数),因为其和10.2.0.4版本的WM_CONCAT一样返回的是VARCHAR2类型
3、 下面介绍下LISTAGG的使用办法:
1、可以发现其是等价的。(例子1)
例子2
|
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31134212/viewspace-2136091/ ,如需转载,请注明出处,否则将追究法律责任。