一次sqlldr匯入慢的解決過程

hanson發表於2019-03-06
今天在客戶處進行培訓時,客戶抱怨到,sqlldr的速度太慢,說是從昨天晚上載入資料到今天上午,都沒有結束。載入的文字檔案大小為10M,大概包含10萬條記錄。按照我的理解,sqlldr幾乎不可能花這麼長的時間的。

於是,讓客戶查詢v$session_wait,發現執行sqlldr載入的session(session id為33)正在等待library cache lock的等待事件。很明顯,sqlldr一直在等待,而不是在進行實際的載入工作。

既然是等待library cache lock,說明有其他的程式鎖定了要載入的表,導致sqlldr
無法獲得該表上的lock。這屬於shared pool裡的一種爭用。

然後,我讓客戶發出下面的SQL:
 select /*+ ordered */
    w1.sid waiting_session,
    h1.sid holding_session,
    w.kgllktype lock_or_pin,
    w.kgllkhdl address,
    decode(h.kgllkmod,0,'None',1,'Null',2,'Share',3,'Exclusive','Unknown') mode_held,
    decode(w.kgllkreq,0,'None',1,'Null',2,'Share',3,'Exclusive','Unknown') mode_requested
    from dba_kgllock w, dba_kgllock h, v$session w1, v$session h1
    where (((h.kgllkmod != 0) and (h.kgllkmod != 1)
     and ((h.kgllkreq = 0) or (h.kgllkreq = 1)))
     and (((w.kgllkmod = 0) or (w.kgllkmod = 1))
     and ((w.kgllkreq != 0) and (w.kgllkreq != 1))))
     and w.kgllktype = h.kgllktype
     and w.kgllkhdl = h.kgllkhdl
     and w.kgllkuse = w1.saddr
     and h.kgllkuse = h1.saddr;

該sql可以很清楚的顯示出,誰阻礙了誰。查詢結果顯示23號session鎖定了33號session。於是發出下面的sql:
select sql_text from v$sql
where hash_value=(select sql_hash_value from v$session where sid=23);

可以看到23號session在幹什麼。結果發現它在執行重新rebuild索引的命令:
alter index XXX rebuild online;

而該索引正是要載入的表上的索引,於是可以肯定,該語句阻塞了sqlldr的操作。
於是在確定了23號session無關緊要以後,將該session直接切斷即可。切斷該session以後,sqlldr很快就完成了載入資料的工作。

結論:
當發現oracle裡某個動作特別慢的時候,先檢視一下它在等待什麼。
可能並不一定是這個動作本身慢,而是其他的原因導致它無法進行下去。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9842/viewspace-331084/,如需轉載,請註明出處,否則將追究法律責任。

相關文章