一个表info 有3百万条数据,建立复合索引包括了查询条件和order by的所有字段,如下sql执行正常,约0.03秒
select *  from (
    SELECT A.*, ROWNUM RN FROM (
select * from info t
        where t.country_id = 1
            and t.province_id = 1
            and t.city_id = 1
            and t.date_flag = 0
            order by t.id desc
    ) A 
WHERE ROWNUM <= 50 但是遇到一个怪异的问题,我只在这个sql外面再加一个 select *,变成 select * from (  上面的sql  ),其他都不变,查询时间就变成了3秒多。这是为什么。

解决方案 »

  1.   


    在pl/sql developer里查看执行计划
    两条sql都用到了那个索引。
      

  2.   

    多层嵌套会影响效率.
    分页查询可以使用分析函数以提高效率,sql看着也舒服些.
    with t as (select t.*,rownumber()over(order by id desc) rn from info t
      where t.country_id = 1
      and t.province_id = 1
      and t.city_id = 1
      and t.date_flag = 0)
    select * from t where rn<=50
      

  3.   

    参照下面帖子
    http://topic.csdn.net/u/20100819/10/86ca5d1b-8925-4582-b8f6-693ba82e69c2.html
      

  4.   


    运行了一下,执行用48秒。再加一个 select *后速度明显变慢是什么原因呢?
      

  5.   

    加上一层select * 意味着你要把子查询的结果送回到内存中再取出来,而不是直接取出,当然会慢,你嵌套个10层select * from()试试看,速度要慢很多很多。
    另外,不推荐4L的用窗口函数的做法写分页,事实上窗口函数是一种非常消耗资源的写法,一般在不得不用的情况下才会使用它。
      

  6.   

    加上一层select * 意味着你要把子查询的结果送回到内存中再取出来,而不是直接取出,当然会慢,你嵌套个10层select * from()试试看,速度要慢很多很多。
    另外,不推荐4L的用窗口函数的做法写分页,事实上窗口函数是一种非常消耗资源的写法,一般在不得不用的情况下才会使用它。
      

  7.   


    不对啊,分析函数乃Oracle自带的,当然效率比自己写的要高,大多数情况是这样的,不然,偶然Oracle也不回搞出一套分析函数
      

  8.   


    oracle为什么要自带函数?因为应用需要这些函数,并不是说用这些函数的时候不消耗性能,虽然窗口函数对比递归查询来说效率要高,但它也是非常吃资源的,要进行分组排序操作,相比而言,不带函数的子查询一般会更快。
      

  9.   


    你的说话是没错啦,确实效率是高了,但是也同样消耗资源,我的意思是,Oracle提供这么一个强大的分析函数,当然有它的用意,我们能在实际的应用中,若能用分析函数之类的,当然首选,毕竟是Oracle为我们提供的,肯定比我们自己写的那些复杂的SQL实现相同的功能效率要高的多,我没别的意思
      

  10.   

    慢是一定的,
    你外面多加了个select * from 你的查询结果
    就等于从你的查询结果中又全遍历了一遍,所以肯定会慢呀。