不当使用 union all 导致的SQL解析时间过长的问题优化
在帮助用户优化应用过程中,发现用户大量使用union all 导致SQL解析非常缓慢的问题。考虑到这个问题很有代表意义,我觉得很有必要对于问题进行总结。
一、用户例子
WITH company_user_temp AS (SELECT '00629999000100260000' AS company_code
FROM dual
UNION ALL
SELECT '00250033000000000000' AS company_code FROM dual
UNION ALL
SELECT '00630005000300000000' AS company_code FROM dual
UNION ALL
SELECT '00460207000000000000' AS company_code FROM dual
UNION ALL
SELECT '00420089000000000000' AS company_code FROM dual
UNION ALL
SELECT '00630008000100000000' AS company_code FROM dual
UNION ALL
SELECT '00630013001000000000' AS company_code FROM dual
UNION ALL
SELECT '00620035001900000000' AS company_code FROM dual
。。。
用户大量使用值的union all,导致90%的时间耗在SQL解析上。
-> Seq Scan on dual dual_1458 (cost=0.00..1.01 rows=1 width=0) (actual time=0.003..0.004 rows=1 loops=1)
-> Seq Scan on dual dual_1459 (cost=0.00..1.01 rows=1 width=0) (actual time=0.005..0.005 rows=1 loops=1)
-> Seq Scan on dual dual_1460 (cost=0.00..1.01 rows=1 width=0) (actual time=0.003..0.004 rows=1 loops=1)
-> Seq Scan on dual dual_1461 (cost=0.00..1.01 rows=1 width=0) (actual time=0.003..0.004 rows=1 loops=1)
Planning Time: 5081.423 ms
Execution Time: 43.726 ms
(1466 rows) Time: 5230.600 ms (00:05.231)
二、问题分析
由于SQL有大量的union all,针对union all 的每个部分,SQL 都要进行解析。 由于整个SQL涉及2000多张表 (dual),整个性能非常差。考虑以下修改方式:
with company_user_temp as (select * from (values('00629999000100260000'), ('00250033000000000000')) as company_code )
select count(*) from company_user_temp;
通过这种方式,可以减少整条SQL涉及表的数量,提升SQL解析的性能。
三、验证分析
由于SQL过长,无法实际修改验证,构建以下动态SQL进行验证。
1、union 方式
test=# declare
test-# v_sql text;
test-# begin
test-# v_sql:= 'WITH company_user_temp AS (';
test-# for i in 1..2000 loop
test-# v_sql:=v_sql||'select '||i||' as company_code from dual union all ';
test-# end loop;
test-# v_sql:=substr(v_sql,0,length(v_sql) - 10) ||') select count(*) from company_user_temp';
test-# execute immediate v_sql;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 6735.076 ms (00:06.735)
test=#
2、values 方式
test=# declare
test-# v_sql text;
test-# begin
test-# v_sql := 'with company_code as (select * from (values(';
test-# for i in 1..2000 loop
test-# v_sql:=v_sql||i||'),(';
test-# end loop;
test-# v_sql:=substr(v_sql,0,length(v_sql) - 2)||') as company_code ) select count(*) from company_code';
test-# execute immediate v_sql;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 10.325 ms
test=#
结论:可以看到,这样修改后,SQL 性能得到了大幅提升。
不当使用 union all 导致的SQL解析时间过长的问题优化的更多相关文章
- (转载)处理SQL解析失败导致share pool 的争用
通过关联x$kglcursorx$kglcursor_child_sqlid视图: 通过使用Oracle10035Event事件可以找到解析失败的SQL: 通过oraclesystemdump也可以找 ...
- 自己实现一个SQL解析引擎
自己实现一个SQL解析引擎 功能:将用户输入的SQL语句序列转换为一个可运行的操作序列,并返回查询的结果集. SQL的解析引擎包含查询编译与查询优化和查询的执行,主要包含3个步骤: 查询分析: 制定逻 ...
- SQL解析在美团的应用
https://tech.meituan.com/SQL_parser_used_in_mtdp.html 数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来 ...
- oracle 基础知识(九)----SQL解析
一,解析过程 二,硬解析,软解析,软软解析 01,硬解析 将SQL语句通过监听器发送到Oracle时, 会触发一个Server process生成,来对该客户进程服务.Server process得到 ...
- 转载:一文详解SQL解析与应用
转载地址:http://www.elecfans.com/emb/20180618696111.html 数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严 ...
- SQL解析器详解
1.概述 最近,有同学留言关于SQL解析器方面的问题,今天笔者就为大家分享一下SQL解析器方便的一些内容. 2.内容 2.1 SQL解析器是什么? SQL解析与优化是属于编辑器方面的知识,与C语言这类 ...
- Pisa-Proxy 之 SQL 解析实践
SQL 语句解析是一个重要且复杂的技术,数据库流量相关的 SQL 审计.读写分离.分片等功能都依赖于 SQL 解析,而 Pisa-Proxy 作为 Database Mesh 理念的一个实践,对数据库 ...
- 如何实现一个SQL解析器
作者:vivo 互联网搜索团队- Deng Jie 一.背景 随着技术的不断的发展,在大数据领域出现了越来越多的技术框架.而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进 ...
- requests的content与text导致lxml的解析问题
title: requests的content与text导致lxml的解析问题 date: 2015-04-29 22:49:31 categories: 经验 tags: [Python,lxml, ...
随机推荐
- 重学ES系列之新型数据结构Map应用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- FTP安装及使用
通过网络传输数据的手段 1. ssh 2. http 3. nfs 4. rsync 5. ftp 6. samba ftp的简介: 1. ftp是应用层协议,是基于TCP 2. 使用21端口 FTP ...
- 华为HMS Core携手超图为三维GIS注入新动能
6月30日,在2022(第五届)GIS软件技术大会GIS基础软件新技术板块论坛上,华为联合超图推出了基于HMS Core 3D Engine开发的高保真三维GIS插件,通过3D渲染技术助力三维GIS实 ...
- 关于android sdk中monitor.exe报错的问题
今天又是被坑的一上午.来总结一下: 1. 首先是找不到monitor的问题: 这个可能是一开始环境配置错误.所以我将android sdk重装了一下就好了 2. 第二个是找到monitor.bat发现 ...
- Mybatis整合第三方缓存
1) 为了提高扩展性.MyBatis定义了缓存接口Cache.我们可以通过实现Cache接口来自定义二级缓存 2) EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点. 3) 整合 ...
- Collection子接口:Set接口
1.Set 存储的数据特点:无序的.不可重复的元素具体的:以HashSet为例说明: 1. 无序性:不等于随机性.存储的数据在底层数组中并非照数组索引的顺序添加,而是根据数据的哈希值决定的. 2. 不 ...
- android studio取消设置代理
看标题感觉就是一个简单的设置,其实只是个大坑啊 https://www.jianshu.com/p/bb6d2bcdd5b5 android studio内虽然设置了 no proxy,但是没起作用, ...
- 基于gitlab 15.1 pages 搭建内部博客一定行版本
背景 基于 gitlab 15.1版 pages 搭建内部博客,参考官方文档,遇到一个又一个坑.之前看到别人吐槽说 gitlab 官方文档很差,我算是理解了.下面一个个说. 开始 按照官方文档的说法, ...
- angular变化检测OnPush策略需要注意的几个问题
OnPush组件内部触发的事件(包括viewChild)会引起组件的一次markForCheck Detached组件内部触发的事件不会引起组件的变化检测 OnPush组件的contentChild依 ...
- rsync 文件备份
# rsync # 实现文件的备份. # 备份位置可以是当前主机,也可以是远程主机. # rsync实现了完全备份和增量备份 # 可以做到:1.将本地主机的文件复制到另一个位置(本地.远程). # 2 ...