1

我有以下查询:

SELECT nvl(sum(adjust1),0)
FROM (
  SELECT
    ManyOperationsOnFieldX adjust1,
    a, b, c, d, e
  FROM (
    SELECT
      a, b, c, d, e,
      SubStr(balance, INSTR(balance, '[&&2~', 1, 1)) X
    FROM
      table
    WHERE
      a >= To_Date('&&1','YYYYMMDD')
      AND a < To_Date('&&1','YYYYMMDD')+1
  )
)
WHERE
  b LIKE ...
  AND e IS NULL
  AND adjust1>0
  AND (b NOT IN ('...','...','...'))
  OR  (b = '... AND c <> NULL)

我试图将其更改为:

SELECT nvl(sum(adjust1),0)
FROM (
  SELECT
    ManyOperationsOnFieldX adjust1
  FROM (
    SELECT
      SubStr(balance, INSTR(balance, '[&&2~', 1, 1)) X
    FROM
      table
    WHERE
      a >= To_Date('&&1','YYYYMMDD')
      AND a < To_Date('&&1','YYYYMMDD')+1
      AND b LIKE '..'
      AND e IS NULL
      AND (b NOT IN ('..','..','..'))
      OR  (b='..' AND c <> NULL)
  )
)
WHERE
  adjust1>0

我的意图是在最里面的查询中进行所有过滤,只给外部查询字段 X ,这是我必须经常操作的字段。但是,第一个(原始)查询需要几秒钟才能执行,而第二个查询甚至不会完成。我等了将近 20 分钟,仍然没有得到答案。

发生这种情况的明显原因是我可能忽略的吗?

这些是他们每个人的计划:

SELECT STATEMENT optimizer=all_rows (cost = 973 Card = 1 bytes = 288)
  SORT (aggregate)
    PARTITION RANGE (single) (cost=973 Card = 3 bytes = 864)
      TABLE ACCESS (full) OF "table" #3 TABLE Optimizer = analyzed(cost=973 Card = 3 bytes=564)


SELECT STATEMENT optimizer=all_rows (cost = 750.354 Card = 1 bytes = 288)
  SORT (aggregate)
    PARTITION RANGE (ALL) (cost=759.354 Cart = 64.339 bytes = 18.529.632)
      TABLE ACCESS (full) OF "table" #3 TABLE Optimizer = analyzed(cost=750.354 Card = 64.339 bytes=18.529.632)
4

2 回答 2

3

您的两个查询不相同。

逻辑运算符ANDOR运算符之前进行评估

SQL> WITH data AS
  2          (SELECT rownum id
  3             FROM dual
  4           CONNECT BY level <= 10)
  5  SELECT *
  6    FROM data
  7   WHERE id = 2
  8     AND id = 3
  9      OR  id = 5;

        ID
----------
         5

所以你的第一个查询意味着:SUM当数据是这种方式时,给我这个分区的大数据。

你的第二个查询的意思是:给我大SUM的(当数据是这种方式时这个分区)或(当数据是这种方式时[没有分区消除因此大全扫描])

AND混合逻辑运算符和时要小心OR。我的建议是使用括号以避免任何混淆。

于 2012-07-19T15:12:11.073 回答
2

这完全取决于您的手术室……试试这个:

SELECT nvl(sum(adjust1),0)
FROM (
  SELECT
    ManyOperationsOnFieldX adjust1
  FROM (
    SELECT
      SubStr(balance, INSTR(balance, '[&&2~', 1, 1)) X
    FROM
      table
    WHERE
      a >= To_Date('&&1','YYYYMMDD')
      AND a < To_Date('&&1','YYYYMMDD')+1
      AND (
          b LIKE '..'
          AND e IS NULL
          AND (b NOT IN ('..','..','..'))
          OR  (b='..' AND c <> NULL)
      )
  )
)
WHERE
  adjust1>0

因为您将 OR 与其他没有括号的 AND 语句内联,所以第二个版本不会将检查的数据限制为仅落在日期过滤器中的行。有关详细信息,请参阅条件优先级的文档

于 2012-07-19T15:11:10.013 回答