简单分析Oracle Having子句


  本文标签:Oracle Having子句

  今天向大家介绍Oracle Having子句,可能好多人还不了解Where子句,没有关系,看完本文你肯定学会SQL子句,希望本文能教会你更多东西  。以下是用Where子句替换Oracle Having子句:

  避免使用Oracle Having子句,Having只会在检索出任何记录之后才对结果集进行过滤  。这个处理需要排序,总计等操作  。假如能通过WHERE子句限制记录的数目,那就能减少这方面的开销  。(非 Oracle中)on、where、Having这三个都能够加条件的子句中,on是最先执行,where次之,Having最后,因为on是先把不符合条件的记录过滤后才进行统计,他就能够减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比Having快点的,因为他过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟Oracle Having子句比较了  。

  在这单表查询统计的情况下,假如要过滤的条件没有涉及到要计算字段,那他们的结果是相同的,只是where能够使用rushmore技术,而Having就不能,在速度上后者要慢假如要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而Having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同  。在多表联接查询时,on比where更早起作用  。

  系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由Having进行过滤  。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里  。

  减少对表的查询:

  在含有子查询的SQL语句中,要特别注意减少对表的查询  。例子:

  SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECTTAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)

  通过内部函数提高SQL效率:

  复杂的SQL往往牺牲了执行效率  。能够掌控上面的运用函数解决问题的方法在实际工作中是很有意义的  。

  使用表的别名(Alias):

  当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上  。这样一来,就能够减少解析的时间并减少那些由Column歧义引起的语法错误  。

  用EXISTS替代IN、用NOT EXISTS替代NOT IN:

  在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接  。在这种情况下,使用EXISTS(或NOT EXISTS)通常将提高查询的效率  。在子查询中,NOT IN子句将执行一个内部的排序和合并  。无论在哪种情况下,NOT IN都是最低效的 (因为他对子查询中的表执行了一个全表遍历)  。为了避免使用NOT IN ,我们能够把他改写成外连接(Outer Joins)或NOT EXISTS  。例子:

  1. SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS 
    (SELECT ‘X FROM DEPT WHERE 
    DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB)
    (低效)SELECT * FROM EMP (基础表) WHERE EMPNO 
    > 0 AND DEPTNO IN
    (SELECT DEPTNO FROM DEPT WHERE 
    LOC = ‘MELB)