隊列等待之enq: TX - row lock contention

【性能優化】隊列等待之enq: TX - row lock contention
問題背景:
客戶反映某條sql DELETE SHAREINNERDOC WHERE SOURCEID=:B1<br/>這個執行時間太長sql

問題解決
1>
查看awr報告:


有隊列等待之enq: TX - row lock contention,對應的sql也是客戶提供的sql數據庫

enq: TX - row lock contention 一般是Application級別的問題。一般狀況下,Oracle數據庫的等待事件enq: TX - row lock contention會在下列三種狀況下會出現。
(一)第一種狀況,是真正的業務邏輯上的行鎖衝突,如一條記錄被多我的同時修改。這種鎖對應的請求模式是6(Waits for TX in mode 6 :A 會話持有row level lock,B會話等待這個lock釋放。)。不一樣的session更新或刪除同一個記錄。(This occurs when one application is updating or deleting a row that another session is also trying to update or delete. )
(二)第二種狀況,是惟一鍵衝突(In mode 4,惟一索引),如主鍵字段相同的多條記錄同時插入。這種鎖對應的請求模式是4。這也是應用邏輯問題。表上存在惟一索引,A會話插入一個值(未提交),B會話隨後也插入一樣的值;A會話提交後,enq: TX - row lock contention消失。
(三)第三種狀況,是bitmap索引的更新衝突(in mode 4 :bitmap),就是多個會話同時更新bitmap索引的同一個數據塊。源於bitmap的特性:位圖索引的一個鍵值,會指向多行記錄,因此更新一行就會把該鍵值指向的全部行鎖定。此時會話請求鎖的對應的請求模式是4。bitmap索引的物理結構和普通索引同樣,也是 B-tree 結構,但它存儲的數據記錄的邏輯結構爲"key_value,start_rowid,end_rowid,bitmap"。
其內容相似這樣:"‘8088’,00000000000,10000034441,1001000100001111000"
Bitmap是一個二進制,表示 START_ROWID 到 END_ROWID 的記錄,1 表示等於 key_value即‘8088’的 ROWID 記錄, 0 則表示不是這個記錄。
在瞭解bitmap索引的結構以後,咱們就能理解同時插入多條記錄到擁有bitmap索引的表時,就會同時更新bitmap索引中一個塊中的記錄,等於某一個記錄被同時更新,天然就會出現行鎖等待。插入併發量越大,等待越嚴重。
(四)其餘緣由
It could be a primary key problem; a trigger firing attempting to insert, delete, or update a row; a problem with initrans; waiting for an index split to complete; problems with bitmap indexes;updating a row already updated by another session; or something else.性能優化

若是數據庫一出現enq: TX - row lock contention等待,能夠去看v$session和v$session_wait等視圖。在v$session和v$session_wait中,若是看到的event列是enq: TX - row lock contention的,就表示這個會話正處於行鎖等待。該等待事件的請求模式能夠從v$session和v$session_wait的p1列中獲得。
select sid,
chr(bitand(p1, -16777216) / 16777215) ||
chr(bitand(p1, 16711680) / 65535) "Name",
(bitand(p1, 65535)) "Mode"
from v$session_wait
where event like 'enq%';
經過這個SQL能夠將p1轉換爲易閱讀的文字。session

2> sql是個delete語句,查看一下執行計劃,是否有索引
SQL_ID 4ggjbjszghd7x
--------------------
DELETE SHAREINNERDOC WHERE SOURCEID=:B1

Plan hash value: 2749040791
----------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | | | 9 (100)| |
| 1 | DELETE | SHAREINNERDOC | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| SHAREINNERDOC | 11 | 506 | 9 (0)| 00:00:01 |
| 3 | INDEX RANGE SCAN | DSHAREINDEXDOC_SOURCEID | 11 | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
能夠看到SQL走的是INDEX RANGE SCAN,索引名稱DSHAREINDEXDOC_SOURCEID
查看索引的類型爲FUNCTION-BASED NORMAL
函數索引(Function-Based Indexes,FBI),它基於對錶中列進行計算後的結果建立索引。函數索引在不修改應用程序的邏輯基礎上提升了查詢性能。若是沒有函數索引,那麼任何在列上執行了函數的查詢都不能使用這個列的索引。當在查詢中包含該函數時,數據庫纔會使用該函數索引。函數索引能夠是一個B-Tree索引或位圖索引。
用於生成索引的函數能夠是算術表達式,也能夠是一個包含SQL函數、用戶定義PL/SQL函數、包函數,或C調用的表達式。當數據庫處理INSERT和UPDATE語句時,它仍然必須計算函數才能完成對語句的處理。
對於函數索引的索引列的函數查詢能夠經過視圖DBA_IND_EXPRESSIONS來實現,經過以下的SQL語句能夠查詢全部的函數索引:
SELECT * FROM DBA_INDEXES D WHERE D.INDEX_TYPE LIKE 'FUNCTION-BASED%'; 併發


查看這個索引是系統自動建立的,

而條件中引用的SOURCEID沒有合理的索引,只有一個組合索引,兩千萬的數據沒有合理的索引。。
爲SOURCEID字段建立索引並收集統計信息,sql開始引用新的執行計劃,等待事件enq: TX - row lock contention也沒了app

相關文章
相關標籤/搜索