0

嗨,谁能帮我摆脱这个查询形成逻辑

SELECT C.CPPID, c.CPP_AMT_MANUAL  
FROM CPP_PRCNT CC,CPP_VIEW c 
WHERE 
  CC.CPPYR IN (
    SELECT C.YEAR FROM CPP_VIEW_VIEW C WHERE  UPPER(C.CPPNO) = UPPER('123')
    AND C.CPP_CODE       ='CPP000000000053'
    and TO_CHAR(c.CPP_DATE,'YYYY/Mon')='2012/Nov'
    )
  AND UPPER(C.CPPNO) = UPPER('123')
  AND C.CPP_CODE       ='CPP000000000053'
  and TO_CHAR(c.CPP_DATE,'YYYY/Mon') =  '2012/Nov';  

如果我在查询性能和标准方面形成了错误的查询结构,请纠正我。提前致谢

4

2 回答 2

1

如果您有一些索引或分区表,我不会在列上使用函数,而是在变量上使用函数,以便能够使用索引/选择分区。

我也使用 ANSI 92 SQL 语法。您没有指定(或不直接) cpp_prcnt 和 cpp_view 之间的连接条件,因此它实际上是笛卡尔积(交叉连接)

SELECT C.CPPID, c.CPP_AMT_MANUAL  
FROM CPP_PRCNT CC
CROSS JOIN CPP_VIEW c 
WHERE 
  CC.CPPYR IN (
    SELECT C.YEAR 
    FROM CPP_VIEW_VIEW C 
    WHERE  C.CPPNO = '123'
      AND C.CPP_CODE       ='CPP000000000053'
      AND trunc(c.CPP_DATE,'MM')=to_date('2012/Nov','YYYY/Mon')
    )
    AND  C.CPPNO = '123'
    AND C.CPP_CODE       ='CPP000000000053'
    AND trunc(c.CPP_DATE,'MM')=to_date('2012/Nov','YYYY/Mon')

如果您向我们展示 cpp_view_view 的定义(似乎是 cpp_view 的视图)、CPP_VIEW 的定义(如果简单的话)以及您想要实现的目标,我敢打赌还有更多需要改进/修复的东西。

于 2013-01-08T08:08:33.997 回答
0

您可以改进以下几点:

  • 如果可能,在比较中去掉 UPPER() - 这将使任何索引都无用。如果这不可能,请考虑在 UPPER(CPPNO) 上使用基于函数的索引
  • 不要将您的 DATE 列转换为字符串以将其与字符串进行比较 - 反过来做(即将您的字符串转换为日期 => 只需要一次转换,而不是每个表行一次,可以使用索引)
  • 正如 Dileep 所建议的那样,使用 EXISTS 而不是 IN - 可能会更快
于 2013-01-08T08:11:11.693 回答