Update時間過慢效能分析

Samcle_趙捷軒發表於2014-01-02
 

問題分析

update語句是oracle軟體提供的,因此,在使用者程式通過監聽器連線到伺服器程式的這個過程中不會影響到update語句的任何效能問題。在nomount狀態下,作業系統雖然分配給oracle記憶體,例項已經啟動,但此時oracle中僅僅載入了引數檔案,只提供給oracle伺服器一些基本資訊,比如控制檔案地址,例項名等,沒有任何資料存在。和nomount狀態一樣,oracle在啟動到mount狀態下也只不過多裝載了控制檔案,我們的資料庫只有啟動到了open狀態才裝載資料檔案的內容,使用者才能“真正”接觸到這些資料。

當例項已經正常開啟到open狀態下,我們就要分析這個update語句的執行順序。Oracle會首先進行語法檢查,這裡要麼出錯立即顯示報錯資訊,要麼語法書寫正確並直接顯示執行結果,和update語句執行過慢沒有關係。其次oracle會進行語義檢查,這裡進行update操作一定涉及到表,語義檢查就要檢查這個表是否存在,oracle伺服器就會首先到shared pool中的data dictionary cache中檢索是否有該表,如果有,那麼再到shared pool中的library cache裡查詢是否有相同的sql語句被執行過,如果有,那麼直接在記憶體裡就可以完成該update語句的執行,如果沒有,那麼在library cache中生成該條sql語句的執行計劃,以便其它相同sql語句再次被訪問。如果在記憶體中沒有該表,那麼oracle就會去資料庫的db file檔案裡找到該表,然後把它調動到記憶體的data dictionary cache中,以便該表在記憶體中直接被使用。從這步我們可以看出,即使在最差的情況下(shared pool中沒有要查詢的表和相同的sql語句),也就是多了三次i/o操作和生成執行計劃的時間,並沒有造成太大的時間損耗,這應該也不是問題的主要矛盾。oracle在這條sql語句的執行過程中,進行了語法、語義的檢查後,那麼就該執行這條sql語句了,被修改資料的前映象會寫入到undo表空間裡,這些被修改資料可以作為例項恢復使用。此時髒塊也只是在記憶體中(db buffer cache),在達到了一定條件(觸發ckpt程式、四分之一滿、表空間離線等)時,dbwn後臺程式會把髒塊寫入到db file中,在這個過程中,記憶體中會產生相應的重做日誌(redo log buffer),記錄所改變的操作(dml操作),同樣的,在達到一定條件(三分之一滿、1Mcommitdbwr之前)時,lgwr後臺程式會把這些的重做日誌順序寫入到redo log file中,這些重做日誌資訊在例項恢復的時候可以實現前滾。此時Sql語句已經基本執行完畢。

我們可以看到,這個過程中,雖然可能導致update語句執行快慢問題,但都不是主要原因。

那麼,我們要對update語句有個大致瞭解,update屬於dml語句,oracle為了保證事務的一致性,oracle會在操作的那行加上一個行級排他鎖和一個表級共享鎖,以保證在一個使用者操作過程中,其它使用者不能對該使用者當前的會話進行任何操作,此時,如果使用者a正在執行此操作,而該使用者並沒有進行提交操作,事務沒有結束,此時使用者b也在執行這個操作,那麼此時使用者b無法對這個會話進行任何操作,直到使用者a提交或執行ddl操作完成此次事務為止。否則,使用者b將永遠處於等待狀態。我認為這是出現update語句執行過慢的一個主要原因。

綜上所述,我認為該問題產生的原因是有其它使用者同樣對這個語句進行操作所導致的。

小結

    通過這次對‘update時間過慢效能分析’的分析,我能將update語句出現的問題利用體系結構圖梳理出來。同時,在我分析的過程中也是一個複習以前所學的一個過程。我覺得效果很好,對我的幫助也很大,以後我會多分析這樣的問題,提高自己的oracle水平。

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

相關文章