在做项目的过程中,一个页面使用类似例如以下的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效率低下的更多相关文章

  1. 简述项目中优化sql语句执行效率的方法,从哪些方面,sql语句性能如何分析?

    (1)尽量选择较小的列: (2)将where中用的比较频繁的字段建立索引: (3)select中避免使用*: (4)避免在索引列上使用计算.not in和<>等操作: (5)当只需要一行数 ...

  2. SQL优化系列(一)- 优化SQL

     优化SQL SQL开发人员从源代码中发现一条跑得很慢的SQL, 如何优化? DBA从AWR报告中发现一条跑得很慢的SQL,没有源代码或者不想修改源代码怎么办? SQL自动优化工具SQL Tuning ...

  3. WITH+HInt MATERIALIZE 不见得有效

    那个要多次调用才需要物化的. 只调用一次,物化没用 MATERIALIZE  语法:MATERIALIZE  描述:指示优化器将内联视图实体化————执行过程中会创建基于视图的临时表. with dd ...

  4. Oracle三组难缠的hint no_unnest/unnest,push_subq,push_pred--平展化(转)

    经常有人把这三个hint搞混,主如果因为对三种重写道理不清楚.特总结如下.(实验景象为10204)1. no_unnest, unnestunnest我们称为对子查询展开,顾名思义,就是别让子查询孤单 ...

  5. Oracle 11g R2性能优化 SQL TRACE

    作为Oracle官方自带的一种基本性能诊断工具,SQL Trace可以用来评估当前正在运行的SQL语句的效率,同时为该语句生成统计信息等,并保存这些信息到指定路径下的跟踪文件(trace)当中.SQL ...

  6. 如何用 SQL Tuning Advisor (STA) 优化SQL语句

    在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...

  7. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  8. paip.索引优化---sql distict—order by 法

    paip.索引优化---sql distict—order by 法 作者Attilax ,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...

  9. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

随机推荐

  1. 织梦DedeCMS会员登录或退出后如何直接跳转到首页

    织梦dedecms默认情况下的会员登录后会直接跳转到会员中心,退出也是一样,但是如果我们想让会员登录后直接跳转到首页,那该如何实现呢? 经过我们的研究,已经找到解决办法,下面是详细的修改步骤: 首先在 ...

  2. Java基础关于Map(字典)的方法使用

    Java基础关于Map(字典)的方法使用 java中一般用map与hashmap来创建一个key-value对象 使用前提是要导入方法包: import java.util.HashMap: impo ...

  3. 51nod 更难的矩阵取数问题 + 滚动数组优化

    这里要求要走到终点再走回来,可以转化为两个人走. 那么我们可以先粗暴的设f[x1][y1][x2][y2]为第一个人走到(x1, y1), 第二个人走到(x2, y2)的最大价值. 那么这样空间会很大 ...

  4. PatentTips - Device virtualization and assignment of interconnect devices

    BACKGROUND Standard computer interconnects, particularly for personal computers or workstations, may ...

  5. openssl之EVP系列之5---EVP_Encrypt系列函数具体解释(二)

    openssl之EVP系列之5---EVP_Encrypt系列函数详细解释(二)    ---依据openssl doc/crypto/EVP_EncryptInit.pod和doc/ssleay.t ...

  6. cocos2dx 3.0正式版 在mac上新建项目

    触碰科技确定2.x版本号不会再更新了,会一直维护3.x的版本号.于是赶紧看看3.0的,简单浏览一下.类的使用方法和原来的几乎相同,仅仅是 表达的写法变了下,. . . . 以后肯定有非常多变化,速度熟 ...

  7. P2P进入整顿期,平衡风险和收益之间的矛盾是关键

        毫无疑问,P2P网贷进入了其诞生以来最为关键的整顿期,随着大量提现困难.跑路的P2P平台被曝光之后.行业对P2P网贷的发展也多了几分慎重.少了几分浮躁.只是,P2P网贷所面临的问题正是其它不论 ...

  8. python-实现xml字符串替换功能

    今天遇到一个问题,说的是要把一个android res目录下,所有name=xx的字符串的值,自己参照网上的方法,写了一个脚本.记录如下,方便以后使用 #!/usr/bin/python # -*- ...

  9. CentOS下编译安装Apache

    与Apache 2.2.x相比,Apache 2.4.x提供了很多性能方面的提升,包括支持更大流量.更好地支持云计算.利用更少的内存处理更多的并发等.除此之外,还包括性能提升.内存利用.异步 I/O的 ...

  10. 洛谷P1908 逆序对(归并排序)

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...