深入理解父遊標,子游標的概念
父遊標:儲存HASH值,SQL文字--相同SQL語句,就只有一個父遊標
oracle內部是將SQL文字轉化為ASCII值(大小寫ASCII不同)並進行hash函式的運算
父遊標裡主要包含兩種資訊:sql文字以及最佳化目標。父遊標在第一次開啟時被鎖定,直到其他所有的session都關閉該遊標後才被解鎖。當父遊標被鎖定的時候是不能被交換出librarycache的,只有在解鎖以後才能被交換出library cache。父遊標被交換出記憶體時父遊標對應的所有子游標也被交換出library cache。
我們來執行兩條sql語句
select * from t5 where empno=7900;
select * FROM t5 WHERE empno=7900;
然後我們進行查詢
23:47:02 > select sql_id,sql_text,EXECUTIONS,VERSION_COUNT from v$sqlarea where sql_text like '%empno=7900';
SQL_ID SQL_TEXT EXECUTIONS VERSION_COUNT
------------- -------------------------------------------------- ------------- -------------
c2b7t2mu9xfub select * from t5 where empno=7900 1 1
8ujbmb6j5xpc6 select * FROM t5 WHERE empno=7900 1 1
可以看到雖然只是有大小寫不同 但實際上生成了兩個sql_id,所以sql_id是父遊標的辨別標誌
另外一方面,我們也可以知道,一次父遊標就代表了一次硬解析,而硬解析是我們應該完全避免的方式。為此,我們可以cursor_sharing引數與繫結變數的方式來減少父遊標(即硬解析)的產生
先看當前系統的cursor_sharing
00:01:27 > show parameter cursor_sharing
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing string EXACT
1)、EXACT:通常來說,exact值是Oracle推薦的,也是預設的,它要求SQL語句在完全相同時才會重用,否則會被重新執行硬解析操作。
2)、SIMILAR:similar是在Oracle認為某條SQL語句的謂詞條件可能會影響到它的執行計劃時,才會被重新分析,否則將重用SQL。
3)、FORCE:force是在任何情況下,無條件重用SQL。
此時我們執行
select * from t5 where empno=7788;
select * from t5 where empno=7900;
我們進行檢視
00:00:40 > select sql_id,sql_text,EXECUTIONS,PARSE_CALLS,LOADS from v$sqlarea where sql_text like 'select * from t5%';
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS
------------- -------------------------------------------------- ------------- ------------- -------------
85v4jvh5yj733 select * from t5 where empno=7788 1 1 1
c2b7t2mu9xfub select * from t5 where empno=7900 1 1 1
這裡我們解釋下這些的含義
欄位解釋:
PARSE_CALLS 解析的次數
LOADS 硬解析的次數
EXECUTIONS 執行的次數
現在我們改變系統引數再來進行測試
00:15:25 > alter system set cursor_sharing =force;
System altered.
Elapsed: 00:00:00.05
00:17:13 > show parameter cursor_sharing
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing string FORCE
00:17:30 > /
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS
------------- -------------------------------------------------- ------------- ------------- -------------
5sfmgma8jwcna select * from t5 where empno=:"SYS_B_0" 1 1 1
此時oracle會自動的把當前的sql語句改寫為帶繫結變數的sql語句
多進行幾次其他查詢
select * from t5 where empno=7782;
select * from t5 where empno=7499;
00:18:57 > /
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS
------------- -------------------------------------------------- ------------- ------------- -------------
5sfmgma8jwcna select * from t5 where empno=:"SYS_B_0" 3 3 1
可以看到硬解析不會變化
同樣的我們也可以使用繫結變數進行測試
00:24:25 > var x number;
00:24:32 > exec :x:=7900;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
00:24:55 > select * from emp where empno=:x;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------- ---------- --------- ------------- ------------------- ------------- ------------- -------------
7900 JAMES CLERK 7698 1981-12-03 00:00:00 950 30
Elapsed: 00:00:00.00
00:25:14 > exec :x:=7788;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
00:25:56 > select * from emp where empno=:x;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------- ---------- --------- ------------- ------------------- ------------- ------------- -------------
7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 3000 20
00:22:13 > select sql_id,sql_text,EXECUTIONS,PARSE_CALLS,LOADS from v$sql where sql_text like 'select * from emp where%';
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS
------------- -------------------------------------------------- ------------- ------------- -------------
6r15aucqqz440 select * from emp where empno=:x 1 1 1
Elapsed: 00:00:00.08
00:25:34 > /
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS
------------- -------------------------------------------------- ------------- ------------- -------------
6r15aucqqz440 select * from emp where empno=:x 2 2 1
可以看到透過使用繫結變數,可以有效的減少硬解析
子游標
當發生硬解析時,在產生父遊標的同時,則跟隨父遊標會產生相應的子游標,此時V$SQL.CHILD_NUMBER的值為0。
如果存在父遊標,由於不同的執行環境,此時同樣會產生新的子游標,新子游標的CHILD_NUMBER在已有子游標基礎上以1為單位累計。
子游標包括遊標所有相關資訊,如具體的執行計劃、繫結變數,OBJECT和許可權,最佳化器設定等。子游標隨時可以被LRU演算法置換出
library cache,當子游標被置換出library cache時,oracle可以利用父遊標的資訊重新構建出一個子遊標來,這個過程叫reload。
v$sql中中 的每一行表示了一個child cursor,根據hash value和address與parent cursor 關聯。
child cursor有自己的address,即v$sql.child_address。
我們也來看看可能生成子游標的兩種情況
00:17:16 > alter system flush shared_pool;
System altered.
Elapsed: 00:00:02.19
00:30:47 > alter system flush buffer_cache;
System altered.
假設在不同的schema下面有相同的表,我們在不同的schema下面分別執行如下的sql語句
00:38:38 > select * from t6 where empno=7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------- ---------- --------- ------------- ------------------- ------------- ------------- -------------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
00:38:53 > select * from t6 where empno=7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------- ---------- --------- ------------- ------------------- ------------- ------------- -------------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
00:37:25 > select sql_id,sql_text,EXECUTIONS,VERSION_COUNT from v$sqlarea where sql_text like 'select * from t6%';
SQL_ID SQL_TEXT EXECUTIONS VERSION_COUNT
------------- -------------------------------------------------- ------------- -------------
7b2sgq6rbgvpa select * from t6 where empno=7369 2 2
此時我們看到同一個sql_id存在兩個版本的,我們再來看v$sql中的內容
00:43:36 > /
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS HASH_VALUE CHILD_NUMBER
------------- ---------------------------------------- ------------- ------------- ------------- ------------- -------------
7b2sgq6rbgvpa select * from t6 where empno=7369 1 1 1 2931289770 0
7b2sgq6rbgvpa select * from t6 where empno=7369 1 1 1 2931289770 1
可以看到存在了兩個子游標
現在我們再來看另外一種情況
00:48:32 > select * from t6 where empno=7654;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------- ---------- --------- ------------- ------------------- ------------- ------------- -------------
7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 1250 1400 30
Elapsed: 00:00:00.07
00:48:57 > alter session set optimizer_mode=first_rows;
Session altered.
Elapsed: 00:00:00.05
00:49:44 > select * from t6 where empno=7654;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------- ---------- --------- ------------- ------------------- ------------- ------------- -------------
7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 1250 1400 30
00:43:37 > select sql_id,sql_text,EXECUTIONS,VERSION_COUNT from v$sqlarea where sql_text like 'select * from t6%';
SQL_ID SQL_TEXT EXECUTIONS VERSION_COUNT
------------- ---------------------------------------- ------------- -------------
2hx8th12xzgw5 select * from t6 where empno=7654 2 2
Elapsed: 00:00:00.07
00:50:02 > select sql_id,sql_text,EXECUTIONS,PARSE_CALLS,LOADS,HASH_VALUE,CHILD_NUMBER from v$sql where sql_text like 'select * from t6%';
SQL_ID SQL_TEXT EXECUTIONS PARSE_CALLS LOADS HASH_VALUE CHILD_NUMBER
------------- ---------------------------------------- ------------- ------------- ------------- ------------- -------------
2hx8th12xzgw5 select * from t6 where empno=7654 1 1 1 1172291461 0
2hx8th12xzgw5 select * from t6 where empno=7654 1 1 1 1172291461 1
我們可以看到,在改變系統環境改變的情況下,oracle一樣也可能生成新的子游標
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25462274/viewspace-2124985/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle遊標共享,父遊標和子游標的概念Oracle
- 父遊標 子游標和軟硬解析記載-02
- v$sql v$sqlarea和父遊標 子游標記載01SQL
- v$sql v$sqlarea v$sql_shared_cursor及父遊標,子游標SQL
- Oracle - 共享遊標、父子游標、硬軟解析Oracle
- 關於遊標的一些理解
- Oracle顯示遊標的使用及遊標for迴圈Oracle
- 如何理解指向指標的指標?指標
- 深入理解CRM的概念
- JavaScript 原型概念深入理解JavaScript原型
- VUE父傳子,子傳父Vue
- oracle實驗記錄 (子游標與解析)Oracle
- 遊標的學習
- Android 滑鼠游標的圖形合成Android
- 控制input輸入框游標的位置
- 深入探索 C/C++ 陣列與指標的奧祕之一:陣列與指標概念剖析C++陣列指標
- 指標的理解指標
- win10觸控板沒有游標怎麼辦 win10觸控板沒有游標的方法Win10
- 動態遊標的操作~~~
- SQL SERVER 遊標的使用SQLServer
- 深入理解 Golang 指標Golang指標
- 深入理解Vue元件3大核心概念Vue元件
- 操作文字域內游標的jQuery程式碼jQuery
- PLSQL Language Referenc-PL/SQL靜態SQL-游標變數-游標變數作為子程式引數SQL變數
- input 獲取游標位置與設定游標位置
- 子游標過多導致大量mutex爭用故障分析Mutex
- SqlServer遊標的建立與使用SQLServer
- orcale 之遊標的屬性
- Oracle 動態遊標的使用Oracle
- 深入剖析Vue原始碼 - 資料代理,關聯子父元件Vue原始碼元件
- 元件(子傳父)元件
- Stax處理XML(一)——基於游標的查詢XML
- 如何理解Python3中的子類和父類?Python
- java中多型的理解——父類引用指向子類物件Java多型物件
- 游標操作快捷鍵
- 盒模型-深入理解盒模型及相關概念模型
- [佈局概念] 關於CSS-BFC深入理解CSS
- (原創)建立windows域—深入理解域概念薦Windows