同一条sql不同的过滤条件,查询耗时差别很大:
(1) 过滤条件: Fa.Creation_Date >= To_Date('01-06-2011', 'DD-MM-YYYY'),耗时34.211秒
 SELECT count(*)    FROM 
               Fa_Books       Fb,
               Fa_Additions_b Fa
         WHERE Fb.Asset_Id = Fa.Asset_Id
        AND trunc(Fa.Creation_Date) >= To_Date('01-06-2011', 'DD-MM-YYYY')  (2) 过滤条件: Fa.Creation_Date >= To_Date('01-06-2010', 'DD-MM-YYYY'),耗时0.047秒 
SELECT count(*)    FROM 
               Fa_Books       Fb,
               Fa_Additions_b Fa
         WHERE Fb.Asset_Id = Fa.Asset_Id
        AND trunc(Fa.Creation_Date) >= To_Date('01-06-2010', 'DD-MM-YYYY')  确实不知道原因啊,第2条sql查询的数据更多,为什么会更快呢? 可能会有哪些原因?

解决方案 »

  1.   

    如果Fa.Creation_Date字段上建立有索引的话,下面这样写会更快,
    因为在Creation_Date字段上使用函数将会导致索引无效:Fa.Creation_Date >= To_Date('01-06-2010', 'DD-MM-YYYY')
      

  2.   

    可以看下执行计划
    plsql developer工具中F5,也可以用explain语句
      

  3.   

    oracle中好像执行过一个sql的话,第二次执行的话速度会比较快
      

  4.   

    oracle中扫描数据是按行扫描的,每次查询只返回几行数据,sql1数据在表中分布量比较少,可能需要扫描很多数据后才能找到对应条件的数据,但是在sql2中可能就只扫描表中的前几行就能够将数据检索出来。
      

  5.   

    不好意思,写错了,Fa.Creation_Date没有建索引,有问题是在没有用trunc函数的时候,用了函数就都很快了。
    应该是:
    (1) 过滤条件: Fa.Creation_Date >= To_Date('01-06-2011', 'DD-MM-YYYY'),耗时34.211秒
     SELECT count(*) FROM  
      Fa_Books Fb,
      Fa_Additions_b Fa
      WHERE Fb.Asset_Id = Fa.Asset_Id
      AND Fa.Creation_Date >= To_Date('01-06-2011', 'DD-MM-YYYY')   (2) 过滤条件: Fa.Creation_Date >= To_Date('01-06-2010', 'DD-MM-YYYY'),耗时0.047秒  
    SELECT count(*) FROM  
      Fa_Books Fb,
      Fa_Additions_b Fa
      WHERE Fb.Asset_Id = Fa.Asset_Id
      AND Fa.Creation_Date >= To_Date('01-06-2010', 'DD-MM-YYYY')   
      

  6.   

    确定。  Fa.Creation_Date没有建索引,唯一的差别是条件里的时间不同,一个是To_Date('01-06-2010', 'DD-MM-YYYY'),另一个是To_Date('01-06-2011', 'DD-MM-YYYY').
      

  7.   

    你多执行几遍,算下平均时间,如果你先执行To_Date('01-06-2010', 'DD-MM-YYYY'),oracle会把数据读入内存进行缓存,再执行To_Date('01-06-2011', 'DD-MM-YYYY')会直接查询内存,速度很快
      

  8.   


    --按照下面的方法再测测,怀疑是缓存引起的第二次的查询速度变快。
    --清空缓存 
    alter system flush BUFFER_CACHE;
    alter system flush SHARE_POOL;--执行第一个sql语句,关注时间--清空缓存 
    alter system flush BUFFER_CACHE;
    alter system flush SHARE_POOL;--执行第二个sql语句关注时间
      

  9.   

    首先,你可以按照上面BenChiM888的说法在清空缓存后再去执行查询语句。因为oracle中有没有缓存对其查询时间影响还是十分大的。然后作对比,而后你在查看有没有对查询字段建索引,其次查看数据量大小。确定这几个条件再去查看你的语句。
      

  10.   

    试了,不是缓存的事。 
    两个查询唯一的区别是:一个条件是2011-6-1,另一个是2010-6-1。 
    我看了一下记录,在2011-6有几千条记录,但在2010-6没有记录。
    因为使用的是fa.creation_date>=to_date('01-06-2010','DD-MM-YYYY'),查询的时候需要比较时分秒,所以使用2011-6-1的时间会比较久。