ORACLE 9i資料庫優化案例(4) --- 索引改善UPDATE
C>. 索引對於update操作也很重要
接下來是條UPDATE語句:
CPU Elapsd
Buffer Gets Executions Gets per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----------
98,751,515 14,404 6,855.8 7.4 2176.33 2182.08 3309920380
update T_WIKI_DOC_LOCK set DOC_LOCK_USER_ID=:1,DOC_LOCK_START_TI
ME=to_date(:2,¨yyyy-mm-dd hh24:mi:ss¨),DOC_LOCK_HEARTBEAT_TIME=t
o_date(:3,¨yyyy-mm-dd hh24:mi:ss¨),DOC_LOCK_STATE=:4,DOC_LOCK_US
ER_ID_ENCRYPT=:5,DOC_ID_ENCRYPT=:6,DOC_LOCK_USER_IP=:7,DOC_TITLE
=:8,DOC_USER_ID_EN=:9,DOC_USER_NICK=:10 where DOC_ID=:11該語句一小時內執行1萬5千餘次,每小時佔用CPU時間2176.33s,產生邏輯讀近億次,耗費大量系統資源,想想不應該啊,一條簡單的UPDATE語句而已,而且看起來每次只更新了n條記錄(doc_id做為限制條件),還是檢視下執行計劃吧:
SQL> explain plan for
2 update T_WIKI_DOC_LOCK
3 set DOC_LOCK_USER_ID = :1,
4 DOC_LOCK_START_TIME = to_date(:2, ¨yyyy-mm-dd hh24:mi:ss¨),
5 DOC_LOCK_HEARTBEAT_TIME = to_date(:3, ¨yyyy-mm-dd hh24:mi:ss¨),
6 DOC_LOCK_STATE = :4,
7 DOC_LOCK_USER_ID_ENCRYPT = :5,
8 DOC_ID_ENCRYPT = :6,
9 DOC_LOCK_USER_IP = :7,
10 DOC_TITLE = :8,
11 DOC_USER_ID_EN = :9,
12 DOC_USER_NICK = :10
13 where DOC_ID = :11
14 /
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
-------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | 38 | 3 |
| 1 | UPDATE | T_WIKI_DOC_LOCK | | | |
|* 2 | TABLE ACCESS FULL | T_WIKI_DOC_LOCK | 1 | 38 | 3 |
-------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("T_WIKI_DOC_LOCK"."DOC_ID"=TO_NUMBER(:Z))
Note: cpu costing is off
15 rows selected根本原因在於DOC_ID無索引,每次更新均為全表掃描,雖然寫很少,但是讀很多。對於這種型別的SQL語句,解決起來最簡單了,DOC_ID列建立索引即是:
SQL> CREATE INDEX IND_T_WIKI_DOC_LOCK_DOCID ON T_WIKI_DOC_LOCK(DOC_ID);
Index created再次查詢執行計劃確認:
SQL> explain plan for
2
2 update T_WIKI_DOC_LOCK
3 set DOC_LOCK_USER_ID = :1,
4 DOC_LOCK_START_TIME = to_date(:2, ¨yyyy-mm-dd hh24:mi:ss¨),
5 DOC_LOCK_HEARTBEAT_TIME = to_date(:3, ¨yyyy-mm-dd hh24:mi:ss¨),
6 DOC_LOCK_STATE = :4,
7 DOC_LOCK_USER_ID_ENCRYPT = :5,
8 DOC_ID_ENCRYPT = :6,
9 DOC_LOCK_USER_IP = :7,
10 DOC_TITLE = :8,
11 DOC_USER_ID_EN = :9,
12 DOC_USER_NICK = :10
13 where DOC_ID = :11
14 /
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost
--------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | 38 |
| 1 | UPDATE | T_WIKI_DOC_LOCK | | |
|* 2 | INDEX RANGE SCAN | IND_T_WIKI_DOC_LOCK_DOCID | 1 | 38 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T_WIKI_DOC_LOCK"."DOC_ID"=TO_NUMBER(:Z))
Note: cpu costing is off
15 rows selected變成範圍掃的更新,這個結果已經比較理想了。
D>. 統計資訊很重要
對於ORACLE的CBO來說,生成的執行計劃是否智慧,統計資訊所起到的作用非常關鍵,因此上述操作完成後,建議在適當時間段重新生成相關物件的統計資訊,以便ORACLE能夠自動選擇更加合理的執行計劃:
begin
dbms_stats.gather_table_stats(user,¨T_WIKI_DOC_TOPICS¨,method_opt => ¨FOR ALL INDEXED COLUMNS ¨);
dbms_stats.gather_table_stats(user,¨T_WIKI_EVENT¨,method_opt => ¨FOR ALL INDEXED COLUMNS ¨);
dbms_stats.gather_table_stats(user,¨T_WIKI_DOC_LOCK¨,method_opt => ¨FOR ALL INDEXED COLUMNS ¨);
end;整個優化操作至此告以段落,沒錯,就是幾個索引,推薦再返回到前頁看看系統效能的前後對比,我想,這將更有助於加深印象吧!
另外,必須說明,並不是說所有資料庫效能問題,通過文中提到的這種方式都能予以處理,本文僅闡述一種方式,一種思路,一種特定環境下的優化實施過程,用上那經典的四個字:僅供參考!
通過現象來判讀,根據現狀來入手,再進行優化的操作就不會再像之前那樣,總感覺無從著手了!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7607759/viewspace-681170/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle 9i資料庫做spaOracle資料庫
- Oracle優化案例-分割槽索引之無字首索引(六)Oracle優化索引
- Oracle優化案例-正確的使用索引(二)Oracle優化索引
- Oracle優化案例-自定義函式索引(五)Oracle優化函式索引
- 資料庫效能優化-索引與sql相關優化資料庫優化索引SQL
- Oracle效能優化-SQL優化(案例一)Oracle優化SQL
- Oracle效能優化-SQL優化(案例二)Oracle優化SQL
- Oracle效能優化-SQL優化(案例三)Oracle優化SQL
- Oracle效能優化-SQL優化(案例四)Oracle優化SQL
- 資料庫系列:MySQL索引優化總結(綜合版)資料庫MySql索引優化
- Oracle優化案例-(三十四)Oracle優化
- Oracle優化案例-使用with as優化Subquery Unnesting(七)Oracle優化
- oracle資料庫調優描述Oracle資料庫
- Oracle效能優化-資料庫CPU使用率100%Oracle優化資料庫
- 資料庫優化 - SQL優化資料庫優化SQL
- oracle資料庫建立、刪除索引等操作Oracle資料庫索引
- 資料庫優化資料庫優化
- Oracle資料庫壞塊典型案例分析Oracle資料庫
- Oracle優化案例-union代替or(九)Oracle優化
- SQL優化案例-分割槽索引之無字首索引(六)SQL優化索引
- 效能調優-Mysql索引資料結構詳解與索引優化MySql索引資料結構優化
- MySQL 優化六(InnoDB 下 update 資料出現表鎖之優化)MySql優化
- Oracle資料庫中的不可見索引 invisible indexOracle資料庫索引Index
- Oracle資料庫壞塊典型案例擴充Oracle資料庫
- 資料庫優化SQL資料庫優化SQL
- MySQL資料庫優化MySql資料庫優化
- 【資料庫資料恢復】Oracle資料庫誤truncate table的資料恢復案例資料庫資料恢復Oracle
- Oracle優化案例-擴充套件統計資訊(十四)Oracle優化套件
- SQL優化案例-自定義函式索引(五)SQL優化函式索引
- SQL優化案例-正確的使用索引(二)SQL優化索引
- oracle全文索引之同步和優化索引做了什麼Oracle索引優化
- 資料庫索引資料庫索引
- Oracle優化案例-join列索引缺失導致的sql效能問題(二十六)Oracle優化索引SQL
- 掌握Oracle資料庫效能調優方法Oracle資料庫
- Oracle優化案例-定位start with connect by遞迴死迴圈資料(二十二)Oracle優化遞迴
- Oracle案例11——Oracle表空間資料庫檔案收縮Oracle資料庫
- 資料庫優化之臨時表優化資料庫優化
- Oracle優化案例-又見union代替or(二十)Oracle優化
- Oracle某行系統SQL優化案例(三)OracleSQL優化