select   * 
from   att_idcard   a 
where   a.in_out='E' 
and   to_char(input_time,'yyyymmdd')='20080117' 
and     not   exists   ( 
select   id_card 
from   emp_master   b 
where   b.id_card=a.card_id 
and   b.status   in   ('P','W') 
) 以上脚本执行比较慢,望高手帮助优化一下。

解决方案 »

  1.   

       to_char(input_time,'yyyymmdd')='20080117'   
    where这个 条件 会限制 索引 的 使用 
      

  2.   

    att_idcard 以 card_id 和 input_time 为索引, emp_master以empno为索引,数据量在万条左右
      

  3.   

    to_char(input_time,'yyyymmdd')='20080117'   这句话对性能影响最大!!!建议改成
    Input_Time < ( To_Data( '20080117', 'YYYYMMDD' ) + 1 ) And
    Input_Time >= To_Data( '20080117', 'YYYYMMDD' ) And
      

  4.   

    同ls
    加了to_char(input_time,'yyyymmdd'),使得原索引不得利用
      

  5.   

    1.如果emp_master表中id_card字段的重复度比较平均且不高,而且没有为空的情况,请先建一个索引
    2.修改 to_char(input_time,'yyyymmdd')='20080117' ,使用函数没有办法使用索引。要不就建一个函数索引,但建议修改成4楼的那样
    3.查询自己的sql执行的执行计划,考虑你的记录数不是太多,一般的优化应该就可以达到目的
    下面的sql语句仅供参考 (index线索中的ind为假定的index) 
    select /*+index(a,ind_att_idcard_inputtime)*/*   
    from       att_idcard       a   
    where
    not  exists (   
    select /*+index(b,ind_emp_master_idcard)*/  id_card   
    from       emp_master       b   
    where       b.id_card=a.card_id   
    and       b.status       in       ('P','W')   
    )  and a.in_out='E' and a.input_time<to_data('200801117','YYYYMMDD')+1 and a.input_time>= to_data('200801117','YYYYMMDD')+1
      

  6.   

    多谢各位的热心帮助:
    最后自己写成这样的语句:
    select a.*,b.empno,b.id_card,b.e_full_name,b.date_retired
    from att_idcard a , emp_master b  
    where a.card_id=b.id_card(+)
    and   a.in_out='E'
    and   a.input_time >= to_date('20080117000000','yyyymmddhh24miss')
    and   a.input_time <  to_date('20080118000000','yyyymmddhh24miss')
    and   (
    (b.status ='R' and   b.date_retired <a.input_time)
    or    b.status is null)性能大幅度提高了,谢谢。