SQL Where子句与子查询

时间:2015-08-23 10:54:33

标签: sql oracle subquery query-optimization where

我已经在SQL查询中阅读各种帖子了。

但有没有人知道在使用子查询时它们如何运作?我使用的是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使用率吗?

1 个答案:

答案 0 :(得分:0)

目前尚不清楚您对第二个查询的意图,实际上是无效的。无论如何,我觉得在你的情况下使用子查询是没有意义的。您希望从满足关注类型,人员和特定日期条件的表中进行选择。因此,从该表中选择并将您的条件放在WHERE子句中,就像使用第一个查询一样。我甚至不知道子查询如何在这里提供帮助,因为第一个查询已经是解决问题的直接方法。

简单的规则:让您的查询尽可能简单。这使得它们可读,易维护且易于处理优化器。

至少在PER_ABSENCE_ATTENDANCES(PERSON_ID, ABSENCE_ATTENDANCE_TYPE_ID)上应该有一个索引。甚至在PER_ABSENCE_ATTENDANCES(PERSON_ID, ABSENCE_ATTENDANCE_TYPE_ID, DATE_START, DATE_END)上也好多了。对于后者,索引中不仅包含所有条件,以便快速访问表记录,甚至查询中所需的所有数据,因此表本身不会#39; t必须阅读。