11g新特性之自適應游標共享(Adaptive Cursor Sharing)


自適應游標共享會使包含綁定變量的單個語句擁有多個執行計划,所謂自適應是指執行計划會依據綁定變量的具體值而適配一個最適合該值的執行計划。

 隱藏參數_optimizer_adaptive_cursor_sharing=TRUE 開啟或關閉此特性。

首先:游標是否可以被ACS使用,首先游標必須是綁定變量敏感的游標,也就是說最優的執行計划會依賴於綁定變量具體的值。數據庫會監控綁定變量敏感的游標,觀察是否不同的執行計划會對不同的綁定變量值有好處。

游標在以下兩個條件滿足的時候會被標記為綁定變量敏感的游標:

1.優化器通過綁定變量窺測去做選擇性評估。

2.在綁定變量的列上存在直方圖信息。

等等

對於傳入的每個新的游標的具體值,數據庫會記錄語句執行時的統計信息,語句執行完后,數據庫會對比這次執行的統計信息與之前執行的統計信息,如果兩者差距很大,則數據庫會將該游標標記為 bind-aware 的游標。

當一個游標被標記為 bind-aware的游標后,只要綁定變量的值落入之前收集的綁定變量值與選擇率的直方圖內,優化器就會重用一個已經存在並且對該綁定變量來說最優的執行計划,如果綁定變量的值沒有落入上述直方圖內,則會進行硬解析,由此可見,自適應游標共享的好處是既減少了硬解析的次數,對於不同的綁定變量值來說又能找到一個合適它的執行計划。

游標合並:

當優化器創建新的執行計划為 bind-aware的游標后,如果該執行計划和一個已經存在的游標相同的時候,在這種情況下,優化器會合並游標去節省內存空間,數據庫會擴大選擇性范圍去包括新的綁定變量值的選擇性。

游標共享相關的性能視圖:

  • V$SQL 去檢查一個游標是否是 bind-sensitive 以及bind-aware的游標。

  • V$SQL_CS_HISTOGRAM 有綁定變量,選擇性,執行次數的直方圖。

  • V$SQL_CS_SELECTIVITY 包括綁定變量對選擇性范圍。

  • V$SQL_CS_STATISTICS summarizes 包括優化器是否將某個游標標記為bind_aware 的統計信息。
SQL> var v_own varchar2(100);
SQL> exec :v_own:='sys';
PL/SQL procedure successfully completed
v_own
---------
sys

SQL>select count(object_name) from testtab where owner=:v_own;
COUNT(OBJECT_NAME)
------------------
                 0
v_own
---------
sys

SQL> select count(object_name) from testtab where owner=:v_own;
COUNT(OBJECT_NAME)
------------------
                 0

  檢查執行計划

L_ID  85man3fnzwka5, child number 0
-------------------------------------
select count(object_name) from testtab where owner=:v_own
 
Plan hash value: 1556530801
 
-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |      1 |        |       |     2 (100)|          |      1 |00:00:00.01 |       3 |
|   1 |  SORT AGGREGATE              |          |      1 |      1 |    83 |            |          |      1 |00:00:00.01 |       3 |
|   2 |   TABLE ACCESS BY INDEX ROWID| TESTTAB  |      1 |      1 |    83 |     2   (0)| 00:00:01 |      0 |00:00:00.01 |       3 |
|*  3 |    INDEX RANGE SCAN          | IND_TEST |      1 |      1 |       |     2   (0)| 00:00:01 |      0 |00:00:00.01 |       3 |
-----------------------------------------------------------------------------------------------------------------------------------
 
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
 
   1 - SEL$1
   2 - SEL$1 / TESTTAB@SEL$1
   3 - SEL$1 / TESTTAB@SEL$1
 
Outline Data
-------------
 
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
      DB_VERSION('11.2.0.3')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_RS_ASC(@"SEL$1" "TESTTAB"@"SEL$1" ("TESTTAB"."OWNER"))
      END_OUTLINE_DATA
  */
 
Peeked Binds (identified by position):
--------------------------------------
 
   1 - (VARCHAR2(30), CSID=178): 'sys'
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   3 - access("OWNER"=:V_OWN)
 
Column Projection Information (identified by operation id):
-----------------------------------------------------------
 
   1 - (#keys=0) COUNT("OBJECT_NAME")[22]
   2 - "OBJECT_NAME"[VARCHAR2,128]
   3 - "TESTTAB".ROWID[ROWID,10]
 
Note
-----
   - dynamic sampling used for this statement (level=2)
 

  此時自適應游標共享還沒起作用

select IS_BIND_SENSITIVE,IS_BIND_AWARE,IS_SHAREABLE from v$sql where sql_id='85man3fnzwka5'

       IS_BIND_SENSITIVE    IS_BIND_AWARE    IS_SHAREABLE
       N                    N                Y

列上收集直方圖信息

exec dbms_stats.gather_table_stats(ownname => 'WXC',tabname => 'TESTTAB',method_opt => 'for all indexed columns size auto');

 

SQL> exec :v_own:='SYS';
PL/SQL procedure successfully completed
v_own
---------
SYS

SQL> select count(object_name) from testtab where owner=:v_own;
COUNT(OBJECT_NAME)
------------------
           2021120
v_own
---------
SYS

  再次執行,由於SYS用戶占表中半數以上,所以執行計划應該選擇走全表掃描。

SQL_ID  85man3fnzwka5, child number 1
-------------------------------------
select count(object_name) from testtab where owner=:v_own
 
Plan hash value: 269898743
 
------------------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |      1 |        |       | 18664 (100)|          |      1 |00:00:00.46 |   68720 |
|   1 |  SORT AGGREGATE    |         |      1 |      1 |    72 |            |          |      1 |00:00:00.46 |   68720 |
|*  2 |   TABLE ACCESS FULL| TESTTAB |      1 |   2009K|   137M| 18664   (1)| 00:03:44 |   2021K|00:00:00.36 |   68720 |
------------------------------------------------------------------------------------------------------------------------
 
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
 
   1 - SEL$1
   2 - SEL$1 / TESTTAB@SEL$1
 
Outline Data
-------------
 
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
      DB_VERSION('11.2.0.3')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "TESTTAB"@"SEL$1")
      END_OUTLINE_DATA
  */
 
Peeked Binds (identified by position):
--------------------------------------
 
   1 - (VARCHAR2(30), CSID=178): 'SYS'
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter("OWNER"=:V_OWN)
 
Column Projection Information (identified by operation id):
-----------------------------------------------------------
 
   1 - (#keys=0) COUNT("OBJECT_NAME")[22]
   2 - "OBJECT_NAME"[VARCHAR2,128]
 

  自適應游標共享已經生效如下

select IS_BIND_SENSITIVE,IS_BIND_AWARE,IS_SHAREABLE from v$sql where sql_id='85man3fnzwka5'

SQL_TEXT	                                       IS_BIND_SENSITIVE	IS_BIND_AWARE	IS_SHAREABLE
select count(object_name) from testtab where owner=:v_own 	N	N	Y
select count(object_name) from testtab where owner=:v_own 	Y	N	N
select count(object_name) from testtab where owner=:v_own 	Y	Y	Y

  繼續測試,使綁定變量值為‘WXC’繼續執行,由於wxc只在表中有幾行數據,所以走索引掃描是合適的,執行計划如下 

SQL_ID  85man3fnzwka5, child number 2
-------------------------------------
select count(object_name) from testtab where owner=:v_own
 
Plan hash value: 1556530801
 
-----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |      1 |        |       |    20 (100)|          |      1 |00:00:00.01 |      67 |
|   1 |  SORT AGGREGATE              |          |      1 |      1 |    72 |            |          |      1 |00:00:00.01 |      67 |
|   2 |   TABLE ACCESS BY INDEX ROWID| TESTTAB  |      1 |    446 | 32112 |    20   (0)| 00:00:01 |     64 |00:00:00.01 |      67 |
|*  3 |    INDEX RANGE SCAN          | IND_TEST |      1 |    450 |       |     4   (0)| 00:00:01 |     64 |00:00:00.01 |       3 |
-----------------------------------------------------------------------------------------------------------------------------------
 
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
 
   1 - SEL$1
   2 - SEL$1 / TESTTAB@SEL$1
   3 - SEL$1 / TESTTAB@SEL$1
 
Outline Data
-------------
 
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')
      DB_VERSION('11.2.0.3')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_RS_ASC(@"SEL$1" "TESTTAB"@"SEL$1" ("TESTTAB"."OWNER"))
      END_OUTLINE_DATA
  */
 
Peeked Binds (identified by position):
--------------------------------------
 
   1 - (VARCHAR2(30), CSID=178): 'WXC'
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   3 - access("OWNER"=:V_OWN)
 
Column Projection Information (identified by operation id):
-----------------------------------------------------------
 
   1 - (#keys=0) COUNT("OBJECT_NAME")[22]
   2 - "OBJECT_NAME"[VARCHAR2,128]
   3 - "TESTTAB".ROWID[ROWID,10]
 

可見自適應游標共享確實能根據綁定變量的具體值選擇合適的執行計划。

檢查如下三個視圖,相關信息如下。  

SELECT *  FROM v$sql_cs_histogram where sql_id='85man3fnzwka5'

ADDRESS	HASH_VALUE	SQL_ID	CHILD_NUMBER	BUCKET_ID	COUNT
00000000A84CDFE0	2852014405	85man3fnzwka5	2	0	6
00000000A84CDFE0	2852014405	85man3fnzwka5	2	1	0
00000000A84CDFE0	2852014405	85man3fnzwka5	2	2	0
00000000A84CDFE0	2852014405	85man3fnzwka5	1	0	2
00000000A84CDFE0	2852014405	85man3fnzwka5	1	1	0
00000000A84CDFE0	2852014405	85man3fnzwka5	1	2	6

  SELECT  * from  v$sql_cs_selectivity  where sql_id='85man3fnzwka5'

   	ADDRESS	HASH_VALUE	        SQL_ID	      CHILD_NUMBER	PREDICATE	RANGE_ID	LOW	        HIGH
	00000000A84CDFE0		85man3fnzwka5	2	         =V_OWN   	0	        0.000083	0.000102

  

SELECT * from v$sql_cs_statistics where sql_id = '85man3fnzwka5'

   	ADDRESS	HASH_VALUE	SQL_ID	CHILD_NUMBER	BIND_SET_HASH_VALUE	PEEKED	EXECUTIONS	ROWS_PROCESSED	BUFFER_GETS	CPU_TIME
1	00000000A84CDFE0	2852014405	85man3fnzwka5	2	1699580835	Y	1	258	67	0
2	00000000A84CDFE0	2852014405	85man3fnzwka5	1	3596483694	Y	1	4042242	68720	0

 綁定變量捕獲信息如下

SELECT * from v$sql_bind_capture where sql_id = '85man3fnzwka5'

   	ADDRESS	HASH_VALUE	SQL_ID	CHILD_ADDRESS	CHILD_NUMBER	NAME	POSITION	DUP_POSITION	DATATYPE	DATATYPE_STRING	CHARACTER_SID	PRECISION	SCALE	MAX_LENGTH	WAS_CAPTURED	LAST_CAPTURED	VALUE_STRING
1	00000000A84CDFE0	2852014405	85man3fnzwka5	000000009DA0D950	2	:V_OWN	1		1	VARCHAR2(4000)	178			4000	YES	2016/10/9 7:14:02	WXC
2	00000000A84CDFE0	2852014405	85man3fnzwka5	000000009DA120B8	1	:V_OWN	1		1	VARCHAR2(4000)	178			4000	YES	2016/10/9 7:06:52	SYS
3	00000000A84CDFE0	2852014405	85man3fnzwka5	00000000A84CDB80	0	:V_OWN	1		1	VARCHAR2(4000)	178			4000	YES	2016/10/9 6:55:05	SYS

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM