2015-08-23 53 views
0

我一直在阅读各种职位重新在SQL查询Wheres的位置。SQL Where子句和子查询

但有没有人有任何想法,他们如何使用子查询时的操作?我正在使用Oracle 11g r2。

我问的原因是因为下面有很多CPU正在使用,我想了解如何减少这一点。

例如,原代码:

SELECT GREATEST(ABS.DATE_START, :B1) CURR_REC_SD, 
     LEAST(ABS.DATE_END, :B2)  CURR_REC_ED, 
     ABS.DATE_START     ORIGINAL_DATE_START 
    FROM PER_ABSENCE_ATTENDANCES ABS 
WHERE ABS.ABSENCE_ATTENDANCE_TYPE_ID = :B4 
    AND ABS.PERSON_ID = :B3 
    AND (
     ( ABS.DATE_START BETWEEN :B1 AND :B2 
      OR ABS.DATE_END BETWEEN :B1 AND :B2 
     ) 
     OR (
      :B1 BETWEEN ABS.DATE_START AND ABS.DATE_END 
     ) 
     ); 

VS修改后的代码:

SELECT GREATEST(ABS.DATE_START, :B1) CURR_REC_SD, 
     LEAST(ABS.DATE_END, :B2)  CURR_REC_ED, 
     ABS.DATE_START     ORIGINAL_DATE_START 
    FROM PER_ABSENCE_ATTENDANCES ABS 
WHERE (SELECT ABS.DATE_START, 
       ABS.DATE_END, 
       ABS.DATE_START ORIGINAL_DATE_START 
      FROM PER_ABSENCE_ATTENDANCES 
     WHERE ABS.ABSENCE_ATTENDANCE_TYPE_ID = :B4 
      AND ABS.PERSON_ID = :B3 
     ) 
    AND (
      ( ABS.DATE_START BETWEEN :B1 AND :B2 
      OR ABS.DATE_END BETWEEN :B1 AND :B2 
     ) 
      OR (
       :B1 BETWEEN ABS.DATE_START AND ABS.DATE_END 
     ) 
     ); 

将后者减少我的CPU使用率在那以前的版本?

+0

第二个查询是否会执行并给出您期望的结果? –

+0

它应该给出与第一个相同的结果。如果我在录制时犯了错误,那么我的糟糕之处在于,我的想法是首先会有一个计划要执行,但在第二个计划中,内部较小的选择,然后是外部。 – Sean

+1

我建议执行这两个查询,看看会发生什么。祝你好运。 –

回答

0

目前尚不清楚您打算如何处理第二个查询,因此无效。无论如何,我认为在你的情况下使用子查询没有意义。您想从表格中选择符合类型,人员和某些日期条件。因此,请从该表中选择并将您的标准置于WHERE子句中,就像您在处理第一个查询时一样。我甚至都没有看到,子查询如何能够帮助到这里,因为第一个查询已经是解决问题的直接方法。

简单的规则:保持您的查询尽可能简单。这使得它们具有可读性,可维护性和易于处理的优化器。

至少应该有一个索引PER_ABSENCE_ATTENDANCES(PERSON_ID, ABSENCE_ATTENDANCE_TYPE_ID)。即使在PER_ABSENCE_ATTENDANCES(PERSON_ID, ABSENCE_ATTENDANCE_TYPE_ID, DATE_START, DATE_END)上也更好。对于后者,它不仅在索引中全部为条件,以便快速访问表记录,而且甚至在查询中需要全部数据,所以表本身根本不必被读取。