1.Oracle 数据库;
  2.表Table中有2千多万数据;
  3.执行语句 select * from Table (大概1秒左右)
  4.执行语句 select * from Table  WHERE  SHIP_TIME >=to_date('2005-11-10','yyyy-mm-dd') AND SHIP_TIME <=to_date('2008-11-30','yyyy-mm-dd')   (SHIP_TIME已设定为索引,此句执行时间大概1.5秒)
  
  5.执行语句 select * from Table  WHERE  SHIP_TIME >=to_date('2008-11-10','yyyy-mm-dd') AND SHIP_TIME <=to_date('2008-11-30','yyyy-mm-dd')   (SHIP_TIME已设定为索引,此句执行时间大概3分钟)  请问:为什么第五条语句的执行效率如此差?

解决方案 »

  1.   

    4.执行语句 select * from Table  WHERE  SHIP_TIME >=to_date('2005-11-10','yyyy-mm-dd') AND SHIP_TIME <=to_date('2008-11-30','yyyy-mm-dd')  (SHIP_TIME已设定为索引,此句执行时间大概1.5秒) 
      
    5.执行语句 select * from Table  WHERE  SHIP_TIME >=to_date('2008-11-10','yyyy-mm-dd') AND SHIP_TIME <=to_date('2008-11-30','yyyy-mm-dd')  (SHIP_TIME已设定为索引,此句执行时间大概3分钟) 两句只是开始时间不同,按说第二句数据量应该还少些,怎么会差这么多时间?
      

  2.   

    你全表扫描反而快很多?
    select * from Table
    只需要1S?
      

  3.   

    换个方向来搞.select * from Table  WHERE  to_char(SHIP_TIME,'yyyy-mm-dd') between '2008-11-10' and '2008-11-30'
      

  4.   

    第3句是全表扫描一次,不用过虑比较条件
    第4,5句里select 的字段和第3句一样,但查询时用到函数to_date和比较条件,所以会慢一些第4句和第5句查询时间不一样,我觉得与CPU的负载有关,可能在查询第4句时CPU空闲一些,而查询第5句是CPU忙一些
      

  5.   

    Dear: hebo2005
         事实就是如此,原因不明,所以请教各位。Dear: dawugui 
        
         您的方法还是和我的一样,效率不行
      

  6.   

    Dear hdhai9451 :
        无论何时,总是第五句很慢,第四句都在1.5秒左右.
        换了机器,也是这样 
      

  7.   

    2千多万数据,
    执行语句 select * from Table (大概1秒左右)?这么神奇!
    你用的是开发工具执行的吧,有写工具不是马上给你返回全部数据,而是rownum <= XX行,所以很快.第二条感觉正常,因为你返回的可能是批量数据.第三条就要看下query plan了.
      

  8.   

    是啊,可能只返回100条数据,然后需要时再返回
    照道理,全表扫描没这么快的比如我用TOAD看一个大表,打开时默认是显示500条纪录,打开蛮快的,但如果你想看到最后条纪录,或者排序下,慢死
      

  9.   

    我觉得第4句应该不会那么快,有可能因为你的数据多数在2005-11-10与2008-11-10之间,所以查询时没用到索引,也用到的是全表扫描,而你是用toad或PL/SQL Developer这样的工具查询的,他们会先返回前面几百行的数据,所以显得快些
      

  10.   

    我用的是Toad工具,
    至于第3条语句快,应该就是hdhai9451 说的原因了,
    但4,5条为什么效率相差那么大呢?(数据是平均分布的,差距不大)
      

  11.   

    我觉得不可能同样的语句,一个范围大一个范围小。范围小的还能比范围大的还快吗。肯定是你先执行5
    再执行一次select * from ..的更大范围的,然后再执行4.因为刚查询过的数据还在内存中所以会一下子就罗列差距来了,最好看看执行计划
      

  12.   

    不可能的,
    你用的是什么工具呢?
    4返回的应该只是前几条符合条件的记录,所以快,如果你要返回全部的符合条件的记录一样慢
    5为什么看起来慢呢,因为数据范围小,oracle需要更多的I/O才能找到记录
      

  13.   

    现在只能推测一下:2008-11-10左右,LZ的数据库做过一次删除,后来的新插入的数据物理上被安放在比较零乱的磁盘空间中。
    可以对SHIP_TIME设定的索引rebuild后,再尝试一下。另:从运行到开始显示的等待时间应该是机器组织数据填满显示缓冲区的时间。
    3,4,5可以认为:3--信手拈来,4--略有组织,5--大范围空间查找(如上推测,由于物理上的分散可能有多次页面的调进和调出,
    而每次调进和调出页面时,查找符合条件的记录很少,所以组织首次填满显示缓冲区的时间很长)。
      

  14.   

    三条语句的执行计划以及执行时间分别如下:
    3.计划:
    Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStopSELECT STATEMENT Optimizer Mode=CHOOSE 21 M   89900                           
      TABLE ACCESS FULL UNIWILL.UW_RUNCARD 21 M 3G 89900  
     时间:61msecs4.计划:
    Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStopSELECT STATEMENT Optimizer Mode=CHOOSE 4 M   89900                           
      TABLE ACCESS FULL UNIWILL.UW_RUNCARD 4 M 856 M 89900    
     时间:77msecs5.计划:
    Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStopSELECT STATEMENT Optimizer Mode=CHOOSE 165 K   89900                           
      TABLE ACCESS FULL UNIWILL.UW_RUNCARD 165 K 32 M 89900  
      时间:1.3mis
                          
                            
      

  15.   

    执行计划看出来是第一个返回的数据多啊 cost倒是一样的,因为都是全表扫描
      

  16.   

    to_number(to_char(SHIP_TIME,'yyyy-mm-dd')) between 20081110 and 20081130
    会不会快一些
      

  17.   

    采用如下办法,则可解决此问题:
     SELECT  /*+ Index(uw_runcard uw_runcard_inx11) */  *  FROM UW_RUNCARD  WHERE  SHIP_TIME >=to_date('2008-10-10','yyyy-mm-dd') AND SHIP_TIME <=to_date('2008-11-30','yyyy-mm-dd') 强制索引生效。但多表查询时,即使使用/*+ Index(uw_runcard uw_runcard_inx11) */ ,速度还是很慢.