select round(decode(sum(te1+te2),0,0,sum(te1)/sum(te1+te2)*100),2),ny from sg t 
where data in 
(select distinct t1.data from kj t1,hl t2 
where t1.data =t2.data and qy='dba' and jb='l' and t1.hsj='qj' or t1.fdf='ju')
 and ny between 200902 and 201106 group by ny 上面这个在oracle数据库中,花费时间大约为5秒,用户实在受不了,其中,in 中传入的data数量有70左右,
我试过用一些表连接,时间也没有提高。
请问各位大神如何优化这个sQL语句,十分感激!!!

解决方案 »

  1.   

    不加where条件的SQL语句查出来大概多少记录,加where条件查出来大概多少记录?
      

  2.   

    where data in  改成 where exists 试试
      

  3.   

    where t1.data =t2.data and qy='dba' and jb='l' and t1.hsj='qj' or t1.fdf='ju'
    红色部分要不要加括号呀?感觉怪怪的
      

  4.   

    不加where条件的SQL语句查出来还是二十几条,其实是一样的,不是用了SUM吗,只是得到结果不一样!
      

  5.   

    如果数据量很大的话 尽量别用in来写sql 可以用exists来写
      

  6.   

    我看过一些关于exists和in的帖子。
    好像要被选择的表比子查询中表的结果个数少很多,exists的查询效率才会高于in啊!
    不知是否正确?
      

  7.   

    试试用minus 来减少in 的结果集,in 是查询出2个结果集交集的部分,如果非交集部分交集部分少很多,可以用minus将2个select的结果集去掉交集部分,得到非交集部分,再用not in 提高效率。不知道对你有用么
    select round(decode(sum(te1 + te2), 0, 0, sum(te1) / sum(te1 + te2) * 100),
                 2),
           ny
      from sg t
     where data not in (select data
                      from sg 
                    minus
                    select distinct t1.data
                      from kj t1, hl t2
                     where t1.data = t2.data
                       and qy = 'dba'
                       and jb = 'l'
                       and t1.hsj = 'qj'
                        or t1.fdf = 'ju')
       and ny between 200902 and 201106
     group by ny
      

  8.   

    select round(decode(sum(te1 + te2), 0, 0, sum(te1) / sum(te1 + te2) * 100),
                 2),
           ny
      from sg t
     where data not in (select data
                      from sg 
                    where ny between 200902 and 201106
                   minus
                    select distinct t1.data
                      from kj t1, hl t2
                     where t1.data = t2.data
                       and qy = 'dba'
                       and jb = 'l'
                       and t1.hsj = 'qj'
                        or t1.fdf = 'ju')
       and ny between 200902 and 201106
     group by ny可以将  where 条件执行的优先级很高, 可以将where 条件放到not in的 子查询里面来提高效率
      

  9.   

    数据量大的时候,千万别用in,in是用不到索引的,还有where后面的查询条件可以换下,能淘汰最多数据的条件排在最后,数据库应该是从右执行到左的。
    select round(decode(sum(te1+te2),0,0,sum(te1)/sum(te1+te2)*100),2),ny from sg t
    where ny between 200902 and 201106 
    and data in
    (select distinct t1.data from kj t1,hl t2
    where t1.data =t2.data and qy='dba' and jb='l' and t1.hsj='qj' or t1.fdf='ju')
     group by ny
      

  10.   


    此执行计划是PL/SQL生成的,我看不明白啊,求解释!
    或者哪位大侠有完整的关于执行计划的介绍!
      

  11.   

    没看到cost,但看到好多全表扫描。楼主你看看in里面sql的关联条件是否有索引
      

  12.   


    给你举个例子SQL> conn scott/tiger
    已连接。
    SQL> show user;
    USER 为 "SCOTT"
    SQL> explain plan for
      2  select * from emp;已解释。SQL> select * from table(dbms_xplan.display());PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------
    --------------------
    Plan hash value: 3956160932--------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |    12 |   444 |     3   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS FULL| EMP  |    12 |   444 |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------已选择8行。SQL>
      

  13.   

    这个语句有些问题select round(decode(sum(te1+te2),0,0,sum(te1)/sum(te1+te2)*100),2),ny from sg t  
    where data in  
    (select distinct t1.data from kj t1,hl t2  
    where t1.data =t2.data and qy='dba' and jb='l' and t1.hsj='qj' or t1.fdf='ju')
     and ny between 200902 and 201106 group by ny  
     1、红色标记:and和or并行用,只有and有效。这里你可能写出了一个逻辑错误,这回导致inlist列表很大。会影响性能
    2、黄色 inlins 不用 distince排序。最后你要评估取出的数据是全部,还是部分,如果是少部分,是否有索引。