不当使用 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, ...
随机推荐
- Mac安装Brew包管理系统
Mac安装Brew包管理系统 前言 为什么需要安装brew 作为一个开发人员, 习惯了使用centos的yum和ubuntu的apt, 在mac中有没有这两个工具的平替? 有, 就是Brew. Bre ...
- 合宙Air32F103CBT6开发板上手报告
2022年6月初合宙新上市了 Air32F103 系列 MCU, 市面上 STM32F103 的克隆军队又增加了新的一员. 这次不知道是哪家的贴牌, 分 Air32F103CBT6 和 Air32F1 ...
- UiPath循环活动While的介绍和使用
一.While循环的介绍 先判断条件是否满足, 如果满足, 再执行循环体, 直到判断条件不满足,则跳出循环 二.While循环在UiPath中的使用 1. 打开设计器,在设计库中新建一个Flowcha ...
- .NET程序配置文件操作(ini,cfg,config)
在程序开发过程中,我们一般会用到配置文件来设定一些参数.常见的配置文件格式为 ini, xml, config等. INI .ini文件,通常为初始化文件,是用来存储程序配置信息的文本文件. [Log ...
- Java已知图片路径下载图片到本地
public static void main(String[] args) { FileOutputStream fos = null; BufferedInputStream bis = null ...
- EEPROM存储电路(M24C64芯片)
电可擦写可编程只读存储器(Electrically Erasable Programmable Read-only Memory, EEPROM)实现掉电情况下保存数据,设计温湿度变送器采用M24C6 ...
- SVM简要介绍
SVM 支持向量机(SVM),是一个用于解决二分类问题的有监督机器学习模型. 1.SVM的两个优点 更高的速度 在有一定的样本数量支持下(成千上万张),具有比其他模型有更好的效果 2.SVM的工作过程 ...
- windows配置skywalking集群
一.zookeeper 准备配置三个zookeeper,因为我是单台模拟,所以需要使用不同的端口,使用版本是apache-zookeeper-3.6.3-bin (必须是3.5+) 1.第1个zook ...
- NGINX屏蔽垃圾爬虫
if ($http_user_agent ~* (80legs.com|Abonti|AcoonBot|Acunetix|adbeat_bot|AddThis.com|adidxbot|ADmantX ...
- 5-1 Vant | 移动组件库
Vant 什么是Vant Vant是一个轻量,可靠的移动端组件库,2017开源 目前 Vant 官方提供了 Vue 2 版本.Vue 3 版本和微信小程序版本,并由社区团队维护 React 版本和支付 ...