使用NOT IN查询性能优化(Oracle Sql Developer)

使用NOT IN查询性能优化(Oracle Sql Developer),sql,oracle,loops,nested-queries,notin,Sql,Oracle,Loops,Nested Queries,Notin,我一直在尝试优化以下查询的性能。我请求这一领域的所有专家帮我一把并提出建议 我有一个应用程序。70k条记录,我的要求是删除重复项。我需要改进以下查询的性能 select * from x.vw_records where id not in (select distinct id from x.vw_datarecords where effective_date >= trunc(sysdate - 30)

我一直在尝试优化以下查询的性能。我请求这一领域的所有专家帮我一把并提出建议

我有一个应用程序。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)
目前,使用count(*)计算行数需要十分钟。建议我调整此查询性能的任何想法


提前感谢。

如果您可以尝试使用exists/not exists子句代替in/not in()。这通常运行得更快。

我想您需要索引。 查询中涉及的表上有哪些索引

&是时候学习如何使用“解释计划”了,这是查询优化的一个基本工具。要得到一个并不难。然而,它们可能更难理解。请在问题中加入解释计划输出

    EXPLAIN PLAN FOR
      <<Your SQL_Statement here>>
    ;

    SET LINESIZE 130
    SET PAGESIZE 0
    SELECT * FROM table(DBMS_XPLAN.DISPLAY);
EXPLAIN计划
;
设置行大小130
将页面大小设置为0
从表中选择*(DBMS\u XPLAN.DISPLAY);


在使用“union”时,使用“select distinct”绝对没有任何好处,不要同时执行这两项操作,只需执行一项即可。

我一直发现,用左连接+其中为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
        )
使用:


此外,有时通过按分组而不是按差别分组,您可以获得明显更好的性能。

您能阅读此查询吗?我不能。我想你在第一个联合之前缺少了一个左括号,作为参考,你查询末尾的左括号不应该在那里。看起来invalidI会看看您是否真的需要在所有地方使用DISTINCT,因为这可能会对性能产生相当大的影响。如果1块的结果与第2块的结果不自然重叠,也可以使用UNION ALL,而不是UNION,因为您要让它做额外的工作来确定是否有重叠。@BrianDeMilia对于这些错误表示抱歉,正在执行查询。我所需要的只是提高查询的性能。如果您有任何想法,请建议我。我只是出于格式化目的编辑了它。为每个表或至少列和索引的列表提供DDL会有所帮助。如果可以避免使用DISTINCT并使用UNION ALL而不是UNION,则可以通过以某种方式使用其他列来避免可能会提高性能的重复项。DISTINCT通常对性能有害。在中使用Exists关键字会给我一个错误。在性能方面,两者几乎相同。对于50行,这两行的获取时间(不存在于不存在的位置)几乎为8秒。[使用解释计划][1][DBMS_XPLAN][2][Oracle Optimizer-解释解释计划][3][1]:[2]:[3]:假设id=name,一家公司可能有两名员工,他们的姓名相同,在不同的字段中。因此,在这种情况下,您需要使用distinct和union。如果我错了,请澄清我。找到我的答案,使用Equi join非常划算。
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