select *
  from (select a.*, rownum RESULT_INDEX
          from (select b.*
                  from vw_order_xj_list b
                 where b.ORDER_ID in
                       (select dwo1.order_id
                          from dsr_work_order dwo1
                         where (dwo1.org_id in
                               (1, 654208, 655362, 655379) or
                               dwo1.belong_job_id in
                               (10000000, 10000001, 10000002, 10000003)))
                 order by b.SEND_DATE desc) a)
 where RESULT_INDEX between 1 and 100

解决方案 »

  1.   

    又In又嵌套
    子查询还用order by
    当然慢了
      

  2.   

    这样你试试,也许能快点,重点如果数据量大,索引很重要
    SELECT *
      FROM (SELECT B.*, ROW_NUMBER() OVER(ORDER BY B.SEND_DATE DESC) AS RESULT_INDEX
              FROM VW_ORDER_XJ_LIST B,
                   (SELECT DWO1.ORDER_ID
                      FROM DSR_WORK_ORDER DWO1
                     WHERE (DWO1.ORG_ID IN (1, 654208, 655362, 655379) OR
                           DWO1.BELONG_JOB_ID IN
                           (10000000, 10000001, 10000002, 10000003))) C
            
             WHERE B.ORDER_ID = C.ORDER_ID) A
     WHERE RESULT_INDEX BETWEEN 1 AND 100
      

  3.   

    dsr_work_order(org_id,belong_job_id)
    vw_order_xj_list(ORDER_ID)上面两表中条件字段是什么类型?是否有索引?
    数据量如何?如果建立索引,选择性怎样?如果是全表扫描,根据条件列的选择性建立索引另外,可以考虑将in改为exists试试,或者使用4楼的表连接方式测试一下效率
    SELECT *
      FROM (SELECT a.*, rownum RESULT_INDEX
              FROM (SELECT b.*
                      FROM vw_order_xj_list b
                     WHERE EXISTS
                     (SELECT 1
                              FROM dsr_work_order dwo1
                             WHERE (dwo1.org_id IN (1, 654208, 655362, 655379) OR
                                   dwo1.belong_job_id IN
                                   (10000000, 10000001, 10000002, 10000003))
                               AND dwo1.order_id = b.order_id)
                     ORDER BY b.SEND_DATE DESC) a)
     WHERE RESULT_INDEX BETWEEN 1 AND 100;
      

  4.   

    楼主tangren的方法我试过效率不及我贴出来的方法,我贴出来的耗时30S左右,但是在并发时就好超时,
    dsr_work_order(org_id,belong_job_id) --- 数据量达到百万
    vw_order_xj_list(ORDER_ID)           ---数据量达到几十万
    order_id是主键索引 org_id,belong_job_id都有组合索引
    但是我看执行计划是好像都没有用到
    上面都是全表扫表但是执行计划还可以,下面用到索引了
    select b.*
      from vw_order_xj_list b
     where b.ORDER_ID in
           (select dwo1.order_id
              from dsr_work_order dwo1
             where dwo1.org_id in
                   (1, 654208, 655362))
    union
    select b.*
      from vw_order_xj_list b
     where b.ORDER_ID in
           (select dwo1.order_id
              from dsr_work_order dwo1
             where dwo1.belong_job_id in
                   (10000000, 10000001, 10000002))
    但是效率却不如上面的,不知道是啥原因
      

  5.   

    看in里的条件了,in里的条件是动态变化的,多的达到几十万啊
      

  6.   

    几十万,看来oracle选择全表扫描是最优的。
    如果选择出来记录很多,占b表30%以上,这样优化余地就不是很大了。如果记录较多,使用4楼表连接方式,执行计划使用hash join应该是比较好的。csdn图片只能发链接。复制文本贴
      

  7.   

    恩,我试试,我第一次的帖的那个SQL执行计划显示,视图,和DSR_WORK_ORDR都是全表扫描,但是执行时间却比使用UNION 和exist子查询还少,exist虽然使用了索引但是执行计划却很差啊,不知道各位专家还有什么好的解决方案啊?
      

  8.   

    如果情况允许的话
    试下将org_id,belong_job_id组合索引改为独立的两个索引,
    再将SEND_DATE改为降序索引