在一個表上建立索引後,會導致library cache裡的與此物件有關的遊標被清理出去。
在一個表上建立索引後,會導致library cache裡的與此物件有關的遊標被清理出去。
library cache裡的遊標總是期待能被重用,只有父遊標與子游標同時被重用,才能被叫做一次軟解析。
我今天的實驗,來自於一個疑惑,先看如下實驗:
SQL> create table t as select * from dba_objects;
表已建立。
SQL> select * from t where wner='SCOTT';
已選擇8行。
已用時間: 00: 00: 00.61
SQL> select * from table(dbms_xplan.display_cursor(null,null,'last'));
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 194 (100)| |
|* 1 | TABLE ACCESS FULL| T | 67 | 11859 | 194 (2)| 00:00:03 |
--------------------------------------------------------------------------
已選擇22行。
已用時間: 00: 00: 00.21
SQL> select sql_text ,sql_id from v$sql where sql_text like 'select * from t where%';
SQL_TEXT SQL_ID
---------------------------------------- -------------
select * from t where wner='SCOTT' 5ytkakbws70wb
SQL> create index ind_t on t(owner);
索引已建立。
已用時間: 00: 00: 00.27
SQL> select * from t where wner='SCOTT';
已選擇8行。
已用時間: 00: 00: 00.06
SQL> select * from table(dbms_xplan.display_cursor(null,null,'last'));
Plan hash value: 4013845416
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 8 | 1416 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T | 8 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
已選擇23行。
已用時間: 00: 00: 00.04
實驗現象:
1)第一次執行語句的時候,由於欄位owner上沒有索引,因此執行計劃採用了全表掃描
2)建立了索引後,再次執行這個語句(完全一樣的語句),執行計劃已經改用了索引掃描。
疑問:
前後執行的sql語句是一樣的,而且這個sql語句在建立索引前,還保留在library cache裡,第二次執行的時候,按照我一開始的想法,會發生軟解析,重用之前的解析計劃,可是結果相反,解析計劃已經發生了改變。改為了索引掃描。
那問題出哪了呢?實驗步驟裡,建立索引前,我是確認過此語句還是在library cache裡的,為什麼建立完索引,下次再執行這個語句,就發生了硬解析呢?莫非建立完索引,這個語句被淘汰出library cache裡了?
接著實驗:
SQL> select * from t where wner='NCSI';
未選定行
已用時間: 00: 00: 00.02
SQL> select * from t where wner='NCSITEST';
未選定行
已用時間: 00: 00: 00.03
SQL> select * from t where wner='MM';
未選定行
已用時間: 00: 00: 00.02
SQL> select * from t where wner='SCOTT';
未選定行
已用時間: 00: 00: 00.02
SQL> select sql_text ,sql_id from v$sql where sql_text like 'select * from t where owner%';
SQL_TEXT SQL_ID
---------------------------------------- -------------
select * from t where wner='MM' cvd5kqv65dqsd
select * from t where wner='SCOTT' 5ytkakbws70wb
select * from t where wner='NCSITEST' 41wtwt0byb380
select * from t where wner='NCSI' 7yn8110s175ha
已用時間: 00: 00: 00.04
SQL> create index ind_t on t(owner);
索引已建立。
已用時間: 00: 00: 00.23
SQL> select sql_text ,sql_id from v$sql where sql_text like 'select * from t where owner%';
未選定行
已用時間: 00: 00: 00.03
實驗結論:果然和猜測的一樣。在一個表上建立完索引後,會導致共享池中的有關此物件的遊標被out出library cache。如果下次執行有關這個物件的語句,會導致硬解析。
[ 本帖最後由 wei-xh 於 2010-6-6 17:13 編輯 ]
library cache裡的遊標總是期待能被重用,只有父遊標與子游標同時被重用,才能被叫做一次軟解析。
我今天的實驗,來自於一個疑惑,先看如下實驗:
SQL> create table t as select * from dba_objects;
表已建立。
SQL> select * from t where wner='SCOTT';
已選擇8行。
已用時間: 00: 00: 00.61
SQL> select * from table(dbms_xplan.display_cursor(null,null,'last'));
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 194 (100)| |
|* 1 | TABLE ACCESS FULL| T | 67 | 11859 | 194 (2)| 00:00:03 |
--------------------------------------------------------------------------
已選擇22行。
已用時間: 00: 00: 00.21
SQL> select sql_text ,sql_id from v$sql where sql_text like 'select * from t where%';
SQL_TEXT SQL_ID
---------------------------------------- -------------
select * from t where wner='SCOTT' 5ytkakbws70wb
SQL> create index ind_t on t(owner);
索引已建立。
已用時間: 00: 00: 00.27
SQL> select * from t where wner='SCOTT';
已選擇8行。
已用時間: 00: 00: 00.06
SQL> select * from table(dbms_xplan.display_cursor(null,null,'last'));
Plan hash value: 4013845416
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 8 | 1416 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T | 8 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
已選擇23行。
已用時間: 00: 00: 00.04
實驗現象:
1)第一次執行語句的時候,由於欄位owner上沒有索引,因此執行計劃採用了全表掃描
2)建立了索引後,再次執行這個語句(完全一樣的語句),執行計劃已經改用了索引掃描。
疑問:
前後執行的sql語句是一樣的,而且這個sql語句在建立索引前,還保留在library cache裡,第二次執行的時候,按照我一開始的想法,會發生軟解析,重用之前的解析計劃,可是結果相反,解析計劃已經發生了改變。改為了索引掃描。
那問題出哪了呢?實驗步驟裡,建立索引前,我是確認過此語句還是在library cache裡的,為什麼建立完索引,下次再執行這個語句,就發生了硬解析呢?莫非建立完索引,這個語句被淘汰出library cache裡了?
接著實驗:
SQL> select * from t where wner='NCSI';
未選定行
已用時間: 00: 00: 00.02
SQL> select * from t where wner='NCSITEST';
未選定行
已用時間: 00: 00: 00.03
SQL> select * from t where wner='MM';
未選定行
已用時間: 00: 00: 00.02
SQL> select * from t where wner='SCOTT';
未選定行
已用時間: 00: 00: 00.02
SQL> select sql_text ,sql_id from v$sql where sql_text like 'select * from t where owner%';
SQL_TEXT SQL_ID
---------------------------------------- -------------
select * from t where wner='MM' cvd5kqv65dqsd
select * from t where wner='SCOTT' 5ytkakbws70wb
select * from t where wner='NCSITEST' 41wtwt0byb380
select * from t where wner='NCSI' 7yn8110s175ha
已用時間: 00: 00: 00.04
SQL> create index ind_t on t(owner);
索引已建立。
已用時間: 00: 00: 00.23
SQL> select sql_text ,sql_id from v$sql where sql_text like 'select * from t where owner%';
未選定行
已用時間: 00: 00: 00.03
實驗結論:果然和猜測的一樣。在一個表上建立完索引後,會導致共享池中的有關此物件的遊標被out出library cache。如果下次執行有關這個物件的語句,會導致硬解析。
[ 本帖最後由 wei-xh 於 2010-6-6 17:13 編輯 ]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-664511/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql的新建索引會導致insert被lockedMySql索引
- 淺談library cache裡的爭用(一)
- 一個關於latch: library cache事件的處理事件
- 索引組織表上建立BITMAP索引(一)索引
- 【Oracle】-【建立索引】-建立索引的操作原理與一些體會Oracle索引
- Mysql 會導致索引失效的情況MySql索引
- 關閉資料庫會導致cache的sequence值丟失嗎?資料庫
- Spring中new出一個物件導致的空指標異常Spring物件指標
- 關於NULL值在索引裡的兩個疑惑Null索引
- try{}裡有一個return語句,那麼緊跟在這個try後的finally{}裡的code會不會被執行,什麼時候被執行?
- 設定事件10049跟蹤遊標上的library cache lock/pin獲取過程事件
- 如果你的系統需要在一張很大的表上建立一個索引,你會考慮哪些因素?索引
- node啟動程式-清理由於崩潰導致的沒有關掉的程式
- 設定MEMORY_TARGET會導致RESULT_CACHE_MAX_SIZE在重啟後歸零
- 導致爬蟲被限制的原因有哪些?爬蟲
- 物件導向的方法在遊戲中的應用的一個例子(上)(轉)物件遊戲
- 一個文章表的 MySQL 索引怎麼建立合理MySql索引
- 故障:核心表業務高峰期授權導致library cache lock和mutex x競爭Mutex
- 無業遊民寫的最後一個.net有關專案框架框架
- mybatis 同一張表的資料被對映到 一個結果物件例項 的 多個屬性物件 上MyBatis物件
- 大量"library cache lock"事件導致資料庫無法連線事件資料庫
- 索引組織表上建立BITMAP索引(三)索引
- 索引組織表上建立BITMAP索引(二)索引
- 建立一個物件的集合物件
- 【ASK_ORACLE】Library cache pin 與 library load lock的關係和區別Oracle
- 如何處理頻繁建立物件然後丟棄導致頻繁GC的情況物件GC
- Oracle11g 密碼延遲認證導致library cache lock的情況分析Oracle密碼
- 寫了個分析library_cache dump的AWK,有興趣的可以搞搞
- oracle分割槽表的常規操作導致對索引的影響Oracle索引
- library cache pin和library cache lock的診斷分析
- ddl 導致分割槽表全域性索引unusable索引
- delphi 裡 一個單元的initialization 會被執行幾次
- 怎樣在磁碟上查詢MySQL表的大小?這裡有答案MySql
- 微軟成功清理與朝鮮黑客攻擊有關的 50 個域名微軟黑客
- 有關修改作業系統時間導致例項down掉的一個案例作業系統
- 在同一工程裡,對應同一張表建立兩個不同JNDI名稱的CMP Entity Bean,會不會又有什麼問題?Bean
- 在活動目錄裡面建立物件物件
- 一個建立物件的問題物件