ORACLE使用WITH AS和HINT MATERIALIZE优化SQL解决FILTER效率低下
在做项目的过程中,一个页面使用类似例如以下的SQL查询数据。为了保密和使用方便,我把项目中有关的表名和字段替换使用ORACLE数据库中的系统表和字段。
在我所做的项目中。类似ALL_TABLES的表中大概有8W多条数据,以下这个查询SQL非常慢。
WITH PARAMS AS
(SELECT '' USER_ID, '' SDATE, '%' || '' || '%' SNAME FROM DUAL)
SELECT AU.USERNAME, AU.USER_ID
FROM ALL_USERS AU
INNER JOIN PARAMS PA
ON 1 = 1
INNER JOIN DBA_USERS DU
ON AU.USERNAME = DU.USERNAME
WHERE ((PA.SDATE IS NULL AND PA.USER_ID IS NOT NULL AND
AU.USER_ID = PA.USER_ID) OR (PA.SDATE IS NULL AND PA.USER_ID IS NULL AND
AU.USERNAME NOT IN
(SELECT AU.USERNAME
FROM ALL_USERS AU
INNER JOIN DBA_USERS DEV
ON AU.USERNAME = DEV.USERNAME
INNER JOIN (SELECT OWNER AS USERNAME
FROM ALL_TABLES T
WHERE T.LAST_ANALYZED = TRUNC(SYSDATE)) ATA
ON AU.USERNAME = ATA.USERNAME)) OR
(PA.SDATE IS NOT NULL AND
AU.USERNAME IN
(SELECT AU.USERNAME
FROM ALL_USERS AU
INNER JOIN DBA_USERS PA
ON AU.USERNAME = PA.USERNAME
INNER JOIN ALL_TABLES ATA
ON PA.USERNAME = ATA.OWNER
WHERE TO_CHAR(ATA.LAST_ANALYZED, 'YYYY-MM-DD') = PA.SDATE) AND
AU.USER_ID = PA.USER_ID))
AND DU.PROFILE LIKE 'D%'
AND AU.USERNAME LIKE PA.SNAME
针对上面的SQL语句运行慢的问题。我做了例如以下的分析:
第一步,把语句的WHERE条件后的三个OR都分别和主查询一块运行,运行速度都非常快,放到一块就非常慢。
第二步。对照上面SQL和三个OR拆分出来的三个SQL的运行计划,例如以下图所看到的。发现上面SQL的运行中有一个FILTER,过滤器谓词中用到了NOT
EXISTS,是导致这条SQL跑的慢的原因。
原因找到了。就得想办法把运行计划的FILTER去掉。開始想加HINT。可是实验了非常多HINT。都不起作用。最后的结果还一样,后来想到WITH
AS 能提高SQL的查询速度,就把影响SQL运行的那段SQL放到WITH
AS里面,结果还是一样。后来尝试把HINT
MATERIALIZE和WITH AS
结合使用,改动成例如以下的SQL,查询速度马上提升了非常多。例如以下图所看到的。运行计划中FILTER的NOT
EXISTS不存在了。
WITH PARAMS AS
(SELECT '' USER_ID, '' SDATE, '%' || '' || '%' SNAME FROM DUAL),
USERNAMEDATA AS
(SELECT /*+ materialize */
AU.USERNAME
FROM ALL_USERS AU
INNER JOIN DBA_USERS DEV
ON AU.USERNAME = DEV.USERNAME
INNER JOIN (SELECT OWNER AS USERNAME
FROM ALL_TABLES T
WHERE T.LAST_ANALYZED = TRUNC(SYSDATE)) ATA
ON AU.USERNAME = ATA.USERNAME)
SELECT AU.USERNAME, AU.USER_ID
FROM ALL_USERS AU
INNER JOIN PARAMS PA
ON 1 = 1
INNER JOIN DBA_USERS DU
ON AU.USERNAME = DU.USERNAME
WHERE ((PA.SDATE IS NULL AND PA.USER_ID IS NOT NULL AND
AU.USER_ID = PA.USER_ID) OR (PA.SDATE IS NULL AND PA.USER_ID IS NULL AND
AU.USERNAME NOT IN (SELECT USERNAME FROM USERNAMEDATA)) OR
(PA.SDATE IS NOT NULL AND
AU.USERNAME IN
(SELECT AU.USERNAME
FROM ALL_USERS AU
INNER JOIN DBA_USERS PA
ON AU.USERNAME = PA.USERNAME
INNER JOIN ALL_TABLES ATA
ON PA.USERNAME = ATA.OWNER
WHERE TO_CHAR(ATA.LAST_ANALYZED, 'YYYY-MM-DD') = PA.SDATE) AND
AU.USER_ID = PA.USER_ID))
AND DU.PROFILE LIKE 'D%'
AND AU.USERNAME LIKE PA.SNAME
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmd3ZWl3ZWkxMzA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
总结:
在FILTER中。NOT EXISTS后的SQL语句多次运行,本来数据量就非常大,每次都要运行一遍,结果可想而知。可是使用HINT
MATERIALIZE和WITH AS
结合使用,把内联视图实体化,运行过程中会创建基于视图的暂时表。
这样就不会每次NOT EXISTS都去运行一遍大数据表的扫描,仅仅须要扫描一次就可以。
可是是不是能够在WITHAS中的每一个语句都实体化那?假设WITH
AS中的语句仅仅被调用一次的话,不妨不要使用HINT
MATERIALIZE。由于使用HINT
MATERIALIZE第一次查询会创建基于视图结果的暂时表,这也耗费一些时间。
多次使用的话能够使用HINT
MATERIALIZE。
ORACLE使用WITH AS和HINT MATERIALIZE优化SQL解决FILTER效率低下的更多相关文章
- 简述项目中优化sql语句执行效率的方法,从哪些方面,sql语句性能如何分析?
(1)尽量选择较小的列: (2)将where中用的比较频繁的字段建立索引: (3)select中避免使用*: (4)避免在索引列上使用计算.not in和<>等操作: (5)当只需要一行数 ...
- SQL优化系列(一)- 优化SQL
优化SQL SQL开发人员从源代码中发现一条跑得很慢的SQL, 如何优化? DBA从AWR报告中发现一条跑得很慢的SQL,没有源代码或者不想修改源代码怎么办? SQL自动优化工具SQL Tuning ...
- WITH+HInt MATERIALIZE 不见得有效
那个要多次调用才需要物化的. 只调用一次,物化没用 MATERIALIZE 语法:MATERIALIZE 描述:指示优化器将内联视图实体化————执行过程中会创建基于视图的临时表. with dd ...
- Oracle三组难缠的hint no_unnest/unnest,push_subq,push_pred--平展化(转)
经常有人把这三个hint搞混,主如果因为对三种重写道理不清楚.特总结如下.(实验景象为10204)1. no_unnest, unnestunnest我们称为对子查询展开,顾名思义,就是别让子查询孤单 ...
- Oracle 11g R2性能优化 SQL TRACE
作为Oracle官方自带的一种基本性能诊断工具,SQL Trace可以用来评估当前正在运行的SQL语句的效率,同时为该语句生成统计信息等,并保存这些信息到指定路径下的跟踪文件(trace)当中.SQL ...
- 如何用 SQL Tuning Advisor (STA) 优化SQL语句
在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...
- sql语句优化SQL Server
MS SQL Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了 ...
- paip.索引优化---sql distict—order by 法
paip.索引优化---sql distict—order by 法 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...
- 转载 50种方法优化SQL Server数据库查询
原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...
随机推荐
- angularjs 页面缓存及动态刷新解决方案
一.准备工作 框架:angularjs ui组件库:ionic1 二.页面缓存cache 路由设置cache参数,true为缓存,false为不缓存,代码如下: angular.module('app ...
- SGU 323 Aviamachinations
Aviamachinations Time Limit: 4500ms Memory Limit: 65536KB This problem will be judged on SGU. Origin ...
- ajax动态更新下拉列表
前面做了一个ajax的小demo,今天看一个动态更新下拉列表,或者也叫级联更新下拉列表,这个也是利用ajax的异步调用去后台实现数据请求.然后回到前台完毕下拉列表数据的更新,以增强web应用的交互性. ...
- 26.使用IntelliJ IDEA开发Java Web项目时,修改了JSP后刷新浏览器无法及时显示修改后的页面
转自:https://blog.csdn.net/yuxxz/article/details/51318908 使用IntelliJ IDEA开发Java Web项目时,修改了JSP后刷新浏览器无法及 ...
- Cisco交换机SPAN&RSPAN调试实录
Cisco交换机SPAN&RSPAN设置实录 本文出自 "李晨光原创技术博客" 博客,请务必保留此出处http://chenguang.blog.51cto.com/3 ...
- IOS应用在ios7(iPhone5/iPhone5s)上不能全屏显示
前言 [IOS应用在iOS7系统或者iPhone5/iPhone5s上不能全屏显示,应用画面上下各有1条黑色,但是在其他系统或者型号的手机上却是正常显示 Paste_Image.png Paste_I ...
- 【习题 8-2 UVA-1610】Party Games
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 字符串排序后 显然是n/2-1和n/2这两个字符串进行比较. 设为a,b 找到第一个不相同的位置. 即0..i-1是相同的前缀,然后 ...
- Css学习总结(1)——20个很有用的CSS技巧
1. 黑白图像 这段代码会让你的彩色照片显示为黑白照片,是不是很酷? img.desaturate { filter: grayscale(100%); -webkit-filter: graysca ...
- Dubbo学习总结(3)——Dubbo-Admin管理平台和Zookeeper注册中心的搭建
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提供的功 ...
- 洛谷 P2021 faebdc玩扑克
P2021 faebdc玩扑克 题目背景 faebdc和zky在玩一个小游戏 题目描述 zky有n个扑克牌,编号从1到n,zky把它排成一个序列,每次把最上方的扑克牌放在牌堆底,然后把下一张扑克牌拿出 ...