使用 NOT IN(Oracle Sql Developer)的查询性能优化
Posted
技术标签:
【中文标题】使用 NOT IN(Oracle Sql Developer)的查询性能优化【英文标题】:Query Performance Opttimization using NOT IN(Oracle Sql Developer) 【发布时间】:2014-07-04 14:23:11 【问题描述】:我一直在尝试优化以下查询的性能。我请求这个领域的所有专家给我一个帮助和建议。
我有应用程序。 70k 条记录,我的要求是删除重复项。我需要提高以下查询的性能。
select *
from x.vw_records
where id not in
(select distinct id
from x.vw_datarecords
where effective_date >= trunc(sysdate - 30)
and book in (select book_shortname from x.vw_datarecords))
union
select distinct id
from x.vw_historyrecords
where effective_date >= trunc(sysdate - 30)
and book in (select book_shortname from x.vw_datarecords)
union
select distinct id
from x.vw_transactiondata
where effective_date >= trunc(sysdate - 30)
and book in (select book_shortname from x.vw_datarecords);
union
select distinct id
from x.vw_cashdata
where effective_date >= trunc(sysdate - 30)
and book in (select book_shortname from x.vw_datarecords)
目前数一数需要十分钟。使用计数(*)的行数。建议我调整此查询的性能。
提前致谢。
【问题讨论】:
你能读懂这个查询吗?我不能。 我认为您在第一个联合之前缺少左括号,并且查询末尾的左括号不应该存在,仅供参考。看起来无效 我会看看你是否真的需要在所有地方都使用 DISTINCT,因为这可能会对性能产生很大影响。如果 1 块的结果自然不会与第二块重叠,也请使用 UNION ALL 而不是 UNION,因为您正在让它做额外的工作来确定是否有任何重叠。 @BrianDeMilia 抱歉出现错误,查询正在执行。我需要的只是提高查询的性能。如果您有任何想法,请建议我。 我只是出于格式化目的对其进行了编辑。为每个表或至少一个列和索引列表提供 DDL 会有所帮助。如果您可以通过以一种或另一种方式使用其他列来避免使用 DISTINCT 并使用 UNION ALL 而不是 UNION 来避免可能会提高性能的重复项。 DISTINCT 通常不利于性能。 【参考方案1】:我总是发现用左连接 + where iS NULL 替换 NOT IN(查询)会获得更好的性能
示例而不是:
select *
from x.vw_records
where id not in (
select distinct id
from x.vw_datarecords
where effective_date >= trunc(sysdate - 30)
and book in (
select book_shortname from x.vw_datarecords
)
使用:
select *
from x.vw_records vr
left join vw_datarecords vdr on vr.id = vdr.id
and effective_date >= trunc(sysdate - 30)
and book in (
select book_shortname from x.vw_datarecords
)
where vdr.id IS NULL
此外,您有时可以通过分组而不是区分来获得明显更好的性能。
【讨论】:
找到了我的答案,使用 Equi join 非常划算。【参考方案2】:我怀疑您需要索引。 您在查询中涉及的表上有哪些索引?
& 是时候学习如何使用“解释计划”了,它是查询优化的重要工具。得到一个并不难。然而,它们可能有点难以理解。请在您的问题中包含解释计划输出。
EXPLAIN PLAN FOR
<<Your SQL_Statement here>>
;
SET LINESIZE 130
SET PAGESIZE 0
SELECT * FROM table(DBMS_XPLAN.DISPLAY);
当你使用“union”时,使用“select distinct”绝对是零好处,不要同时做两个,只做一个。
【讨论】:
[使用解释计划][1] [DBMS_XPLAN][2] [Oracle 优化器 - 解释解释计划][3] [1]:docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_xplan.htm [2]:docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm [3 ]:blogs.oracle.com/optimizer/entry/explain_the_explain_plan_white 假设 id=name,一个公司可能有两个同名不同领域的员工。所以在这种情况下,你需要使用 distinct 和 union。如果我错了,请澄清我。【参考方案3】:如果您可以尝试使用存在/不存在子句代替 in/not in (http://www.techonthenet.com/sql/exists.php)。这通常运行得更快。
【讨论】:
对 in 使用 Exists 关键字给我一个错误。在性能方面两者几乎相同。对于 50 行,两者的提取时间(NOT EXISTS 代替 NOT IN)几乎是 8 秒。以上是关于使用 NOT IN(Oracle Sql Developer)的查询性能优化的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)