请教一个sql语句的问题_20051014fw_khhfdb表1192132条记录,主键是djid,另外,对fwdwid字段建有一个索引,对hfrq 字段也建立了一个索引,在toad中执行以下语句:SELECT COUNT (*)
  FROM fw_khhfdb
  WHERE fwdwid =559
     AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
   AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')很快得到结果:12548                         但是执行以下各语句时,费时很久,跟死机一样:SELECT COUNT (*)
  FROM fw_khhfdb
  WHERE (fwdwid =559 or fwdwid = 1119)
     AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
   AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')或者:SELECT COUNT (*)
  FROM fw_khhfdb
  WHERE     hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
   AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')
AND (fwdwid =559 or fwdwid = 1119)或者:SELECT COUNT (*)
  FROM fw_khhfdb
  WHERE HFFS = 1
AND fwdwid =559
     AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
   AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')其中,HFFS 是一个只有0、1两个值的字段,未单独建有索引。请帮我分析一下,多谢!

解决方案 »

  1.   

    第一个语句的执行计划:
    Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop

    SELECT STATEMENT Optimizer Mode=CHOOSE 1   31                         
      SORT AGGREGATE 1 12                           
        VIEW FWGL.index$_join$_001 7 84 31                         
          HASH JOIN 7 84                           
            INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_FWDWID 7 84 39.00002622                         
            INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_HFRQ 7 84 39.00002622                         第二个语句的执行计划:
    Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStopSELECT STATEMENT Optimizer Mode=CHOOSE 1   13                         
      SORT AGGREGATE 1 12                           
        VIEW FWGL.index$_join$_001 13 156 13                         
          HASH JOIN 13 156                           
            INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_HFRQ 13 156 54.25002254                         
            INLIST ITERATOR                                
              INDEX RANGE SCAN FWGL.INX_FW_KHHFDB_FWDWID 13 156 54.25002254                         
    我不太明白,请帮我分析一下
      

  2.   

    试下这个:
    SELECT COUNT (*)
      FROM fw_khhfdb
      WHERE     hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
       AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')
    AND fwdwid = 1119union
    SELECT COUNT (*)
      FROM fw_khhfdb
      WHERE     hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
       AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')
    AND fwdwid =559
    这个和你上面的不是一个意思啊
    SELECT COUNT (*)
      FROM fw_khhfdb
      WHERE HFFS = 1
    AND fwdwid =559
         AND hfrq >= TO_DATE ('2005-10-01', 'yyyy-MM-dd') 
       AND hfrq <= TO_DATE ('2005-10-13', 'yyyy-MM-dd')其中,HFFS 是一个只有0、1两个值的字段,未单独建有索引。
      

  3.   

    注意一下你两个语句使用索引的顺序不同,是导致你两条语句执行效率差距很大的原因。在书写sql语句是应该尽量避免使用or条件,而使用in或者集合操作会提高sql语句的执行速度。
      

  4.   

    另有一个类似表,数据300多万,也用类似的语句去查询,索引也一样,而用or的和不用Or的速度一样,都是一点就出结果,可不可能是表本身的问题,或者是数据库的问题?
      

  5.   

    “另有一个类似表,数据300多万,也用类似的语句去查询,索引也一样,而用or的和不用Or的速度一样,都是一点就出结果,可不可能是表本身的问题,或者是数据库的问题?”,那么执行这两个查询的执行计划是相同的吗?如果不同,可以考虑对表做分析。
      

  6.   

    建立(hfrq,fwdwid)的复合索引
      

  7.   

    因为你的第一种写法是最优的ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并. 
      

  8.   

    建议分析一下数据表和索引,很可能是 fwdwid 这个索引需要重建了