优化一个sql时,想起了建立索引,不过不知道是应该分开建立(一个索引名对应一个字段),还是应该一起建立(一个索引名对应多个字段),这两个在执行上有什么区别。
sql如下
  SELECT "WW_BXB"."BXDBH",   
         "WW_BXB"."ZZBH",   
         "WW_BXB"."WXS",   
         "WW_BXB"."BXZZ",   
         "WW_BXB"."RID",   
         "WW_BXB"."GDXZ",   
         "CALL_DIRE_USER"."LEVEL1",   
         "WW_BXB"."ZONE",   
         "CALL_KH_LEVEL1"."KH_NAME",   
         "CALL_KH_LEVEL2"."KH_NAME",   
         "WW_BXB"."BGY",   
         "WW_BXB"."YD",   
         "WW_BXB"."WXLX",   
         "WW_BXB"."DHPZ_LX",   
         "WW_BXB"."DHPZ_ZT",   
         "WW_BXB"."DHPZ_SJ",   
         "WW_BXB"."DHPZ_CZZ",   
         "WW_BXB"."KSF_DH",   
         "KHXXDB"."KHMC",   
         "WW_BXB"."JZXH",   
         "WW_BXB"."PHONE",   
         "WW_BXB"."FAX",   
         "CALL_DIRE_USER"."MOBILE",   
         "WW_BXB"."KSF_ZCBH",   
         "WW_BXB"."PEPSI_DH",   
         "WW_BXB"."PEPSI_INTERID",   
         "WW_BXB"."PEPSI_ZCBH",   
         "CALL_DIRE_USER"."YYB",   
         "CALL_DIRE_USER"."YYS",   
         "CALL_DIRE_USER"."LINKMAN",   
         "CALL_DIRE_USER"."KH_SF",   
         "CALL_DIRE_USER"."KH_CITY",   
         "CALL_DIRE_USER"."KH_COUNTY",   
         "CALL_DIRE_USER"."KH_TOWN",   
         "CALL_DIRE_USER"."ADDRESS",   
         "WW_BXB"."TSWXLX",   
         "CALL_DIRE_USER"."LEVEL2",   
         "WW_BXB"."KSF_INTERID",   
         "WW_BXB"."TINGHSIN_SOUCE"  
    FROM "WW_BXB",   
         "WW_ZTB",   
         "CALL_DIRE_USER",   
         "CALL_KH_LEVEL1",   
         "CALL_KH_LEVEL2",   
         "KHXXDB"  
  WHERE    ( call_dire_user.level1 = call_kh_level1.id_level1 (+)) and  
         ( call_dire_user.level2 = call_kh_level2.id_level2 (+)) and  
         ( ww_bxb.wxs = khxxdb.khbm (+)) and  
         ( "WW_BXB"."ZJKHBM" = "CALL_DIRE_USER"."ID" ) and  
         ( "WW_BXB"."BXDBH" = "WW_ZTB"."WXDBH" ) 
         and ( ( "WW_ZTB"."PG" = '0' ) AND  ( "WW_BXB"."BXR" not in ('顶津E站','百事E站','EXCEL') ) 
         AND  ("WW_BXB"."DHPZ_ZT" is null OR  "WW_BXB"."DHPZ_ZT" <> '1') 
         AND   ("WW_BXB"."GDXZ" is null OR  "WW_BXB"."GDXZ" <> '08')
         AND  ("WW_BXB"."PDR" is null OR  "WW_BXB"."PDR" like '%') );    疑惑点1.像 where后面的 ( call_dire_user.level1 = call_kh_level1.id_level1 (+)) and  
         ( call_dire_user.level2 = call_kh_level2.id_level2 (+))  这句话,我是把 call_dire_user这个表的level1和level2这两个字段分别建立两个索引,还是把两个字段建立一个索引。
疑惑点2 像 ww_bxb这种表 每个and后都有一个字段限定,我是把这几个字段捏在一起写成一个索引,还是分别建立多个索引?
甚是迷惑

解决方案 »

  1.   

    1、你把索引建在驱动表的连接字段上是没用的,要建在被驱动表的连接字段上,而且连接字段可以建到一起;
    2、后面单表上的条件太复杂,而且还有is null这种,B树索引如果未经任何加工,无论是单字段还是多字段索引处理这种条件都是力不从心的,在各个字段上创建位图索引是个选择,但要求表上不能有并发DML。
      

  2.   


    实际上我觉得你这样的SQL,根本就不需要任何索引,因为这是个统计,每次参与连接的数据量完全不可控,还不如表扫描然后HASH JOIN搞定,这种SQL可以说不适合Oracle来处理,当然其他关系数据库更不行,MPP或者hadoop才是解决之道。
      

  3.   


    实际上我觉得你这样的SQL,根本就不需要任何索引,因为这是个统计,每次参与连接的数据量完全不可控,还不如表扫描然后HASH JOIN搞定,这种SQL可以说不适合Oracle来处理,当然其他关系数据库更不行,MPP或者hadoop才是解决之道。忍不住三连 既然是个统计,那么我就假设这是个仓库类的数据库了,那么一楼的优化可以考虑,因为至少这样的索引可以优化一部分查询(根据条件的不同,有一部分查询可能涉及到的数据量较小)
      

  4.   


    实际上我觉得你这样的SQL,根本就不需要任何索引,因为这是个统计,每次参与连接的数据量完全不可控,还不如表扫描然后HASH JOIN搞定,这种SQL可以说不适合Oracle来处理,当然其他关系数据库更不行,MPP或者hadoop才是解决之道。忍不住三连 既然是个统计,那么我就假设这是个仓库类的数据库了,那么一楼的优化可以考虑,因为至少这样的索引可以优化一部分查询(根据条件的不同,有一部分查询可能涉及到的数据量较小)首先,感谢大神的耐心解答不过本人作为非专业数据人员有些地方不是特别能理解,驱动表就是指左链接的主表被,位图索引从来没用过,如果用的话,针对于这个sql应该怎么写呢
      

  5.   


    实际上我觉得你这样的SQL,根本就不需要任何索引,因为这是个统计,每次参与连接的数据量完全不可控,还不如表扫描然后HASH JOIN搞定,这种SQL可以说不适合Oracle来处理,当然其他关系数据库更不行,MPP或者hadoop才是解决之道。忍不住三连 既然是个统计,那么我就假设这是个仓库类的数据库了,那么一楼的优化可以考虑,因为至少这样的索引可以优化一部分查询(根据条件的不同,有一部分查询可能涉及到的数据量较小)
    实际上我觉得你这样的SQL,根本就不需要任何索引,因为这是个统计,每次参与连接的数据量完全不可控,还不如表扫描然后HASH JOIN搞定,这种SQL可以说不适合Oracle来处理,当然其他关系数据库更不行,MPP或者hadoop才是解决之道。忍不住三连 既然是个统计,那么我就假设这是个仓库类的数据库了,那么一楼的优化可以考虑,因为至少这样的索引可以优化一部分查询(根据条件的不同,有一部分查询可能涉及到的数据量较小)首先,感谢大神的耐心解答不过本人作为非专业数据人员有些地方不是特别能理解,驱动表就是指左链接的主表被,位图索引从来没用过,如果用的话,针对于这个sql应该怎么写呢
    对,驱动表就是主表,就是你这个外连接中记录数更全的那张。位图索引创建语法与普通B树索引差别就一点:  create bitmap index .....
      

  6.   

    忘了说,有一个关键的因素就是这个表肯定是有并发dml
    如何优化很是头疼啊
      

  7.   


    还有个办法,为那几个可能为null的字段设置默认值,然后创建组合索引,不过,如果你的where条件组合多变的话,又要黄了 
      

  8.   

    根据上述的SQL来讲,建立索引是对的,至于一个或多个要看你数据库的能力了,还有最主要的是要优化sql。