主要是时间段那,请将优化后的结果贴出,在线等,即时采用即时给分,谢谢!update Eit a set 
(user_id, full_name, sex, birthday, native_place, duty_code, job_code, company_id, dept_id, email, mobile, phone, update_date, ehr_pk_psndoc, user_type, his_stats )
=
(
select 
user_id, full_name, sex, TO_DATE(birthday, 'YYYY-MM-DD'), native_place,dutycode, job_code, company_id, dept_id, email, mobile, phone, sysdate, ehr_pk_psndoc, '0', '1' 
from v_ehr_eit_users b 
where b.user_name=a.user_name
and substr(b.update_date,1,10)>='2007-03-01' and substr(b.update_date,1,10)<='2007-03-02'
)
where 
exists(
select 1 from v_ehr_eit_users b where b.user_name=a.user_name and substr(b.update_date,1,10)>='2007-03-01' and substr(b.update_date,1,10)<='2007-03-02'
)

解决方案 »

  1.   

    v_ehr_eit_users的update_date字段类型是什么
      

  2.   

    v_ehr_eit_users的update_date字段类型是字符型,郁闷,提供的视图是字符型的,不是日期型
      

  3.   

    给update_date和user_name分别建索引试试
      

  4.   

    最好的办法是建一个这样的substr(b.update_date,1,10)函数索引,试试看
      

  5.   

    update_date字符类型,如果格式是否类似 yyyy-mm-dd hh:mi:ss,可以尝试一下仅仅通过字符串来比较大小
    b.update_date >='2007-03-01 00:00:00'
    and b.update_date < '2007-03-03 00:00:00'
      

  6.   

    lz的意思你的相关表的数据量有多大,需要更新的数据量多大?可否分段commit?
      

  7.   

    前提如下:
    1)如果采取Pl/sql的方式。
    2)满足substr(b.update_date,1,10)>='2007-03-01' and substr(b.update_date,1,10)<='2007-03-02'的内容不是非常多。
    3)其次一个a.user_name对应惟一的一个b.user_name(从你的语句给出的条件所做的假设).则采取以下方案:
    1)给b表在substr(update_date)上建立索引。
    2)建立临时表TEMP 只有user_name字段,可以斟酌放其它字段.
    3)按照时间段拆分查询,如例子,则分为两日2007-03-01和2007-03-02把查询到的user_name 数据插入到临时表temp
    4)修改语句为
      update a set (..)=(select .. from b where b.user_name=a.user_name)
        where exists (select 1 from temp where temp.user_name=a.user_name)
      这样在a,b表格上最终都可以使用到索引。最终无序的防卫则可以分解为多个有序的索引访问。如果你的日期范围不是像上文说的那样狭窄,而是基本上覆盖了整个表格(性能上已经等同于全表scan),则没有必要采取我的方案。