走ORACLE後門cusor_sharing的問題
當cusor_sharing=similar時,在收集了直方圖的列上進行非等查詢時,進行硬解析
SQL> show parameter cursor_sh
NAME TYPE VALUE
------------------------------------ -------------------------------- ------------------------------
cursor_sharing string SIMILAR
SQL> SELECT COUNT(*)
2 FROM USER_HISTOGRAMS
3 WHERE TABLE_NAME = 'T1'
4 AND COLUMN_NAME = 'HEADER_BLOCK';
COUNT(*)
----------
76
[oracle@SOURCE ~]$ cat parse.sql
SELECT B.VALUE FROM V$STATNAME A, V$MYSTAT B WHERE A.STATISTIC# = B.STATISTIC#
AND A.NAME IN ('parse count (hard)');
SQL> SELECT SUM(HEADER_BLOCK) FROM T1 WHERE SEGMENT_TYPE = 'INDEX' AND HEADER_BLOCK > 100;
SUM(HEADER_BLOCK)
-----------------
59390560
SQL> @parse.sql
VALUE
----------
1
SQL> @parse.sql
VALUE
----------
1
SQL> SELECT SUM(HEADER_BLOCK) FROM T1 WHERE SEGMENT_TYPE = 'INDEX' AND HEADER_BLOCK > 101;
SUM(HEADER_BLOCK)
-----------------
59390560
SQL> @parse.sql
VALUE
----------
2
SQL> SELECT SUM(HEADER_BLOCK) FROM T1 WHERE SEGMENT_TYPE = 'INDEX' AND HEADER_BLOCK > 103;
SUM(HEADER_BLOCK)
-----------------
59390560
SQL> @parse.sql
VALUE
----------
3
上面修改HEADER_BLOCK的值,進行了硬解析,下面測試修改等條件的值
SQL> SELECT SUM(HEADER_BLOCK) FROM T1 WHERE HEADER_BLOCK > 103 and SEGMENT_TYPE = 'INDEX';
SUM(HEADER_BLOCK)
-----------------
59390560
SQL> @parse.sql
VALUE
----------
1
SQL> SELECT SUM(HEADER_BLOCK) FROM T1 WHERE HEADER_BLOCK > 103 and SEGMENT_TYPE = 'TABLE';
SUM(HEADER_BLOCK)
-----------------
33745222
SQL> @parse.sql
VALUE
----------
1
沒有進行硬解析
SQL> DECLARE
2 LN_COU NUMBER;
3 LN_VALUE NUMBER;
4 LVC_SQL VARCHAR2(200);
5 BEGIN
6 FOR I IN 1 .. 100 LOOP
7 LVC_SQL := 'SELECT /*+FLAG1*/SUM(HEADER_BLOCK) FROM T1 WHERE SEGMENT_TYPE = ''INDEX'' AND HEADER_BLOCK > ' ||
8 TO_NUMBER(1000 + I);
9 EXECUTE IMMEDIATE LVC_SQL
10 INTO LN_COU;
11 END LOOP;
12 END;
13 /
SQL> SELECT SHARABLE_MEM, VERSION_COUNT, LOADS, INVALIDATIONS
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG1%'
4 AND SQL_TEXT NOT LIKE 'DECLARE%';
SHARABLE_MEM VERSION_COUNT LOADS INVALIDATIONS
------------ ------------- ---------- -------------
1156725 100 100 0
SQL> DECLARE
2 LN_COU NUMBER;
3 LN_VALUE NUMBER;
4 LVC_SQL VARCHAR2(200);
5 BEGIN
6 FOR I IN 1 .. 10000 LOOP
7 LVC_SQL := 'SELECT /*+FLAG1*/SUM(HEADER_BLOCK) FROM T1 WHERE SEGMENT_TYPE = ''INDEX'' AND HEADER_BLOCK > ' ||
8 TO_NUMBER(1000 + I);
9 EXECUTE IMMEDIATE LVC_SQL
10 INTO LN_COU;
11 END LOOP;
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> SELECT SHARABLE_MEM, VERSION_COUNT, LOADS, INVALIDATIONS
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG1%'
4 AND SQL_TEXT NOT LIKE 'DECLARE%';
SHARABLE_MEM VERSION_COUNT LOADS INVALIDATIONS
------------ ------------- ---------- -------------
15035505 1496 1301 0
version_count在執行的時候是一直變化的,最高到達過2000多,然後又下降
在作業系統上做了個指令碼,掛載後臺同時10個一起跑,10分鐘報04031
cursor_charing <> exact 時候,如果SQL中有不等條件,sessin_cursor_cache無作用
先來看下Session_Cached_Cursors關閉的情況
ALTER SESSION SET Session_Cached_Cursors=0;
BEGIN
FOR i IN 1..100 LOOP
EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
END LOOP;
END;
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
100 100 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
語句解析了100次
SQL> ALTER SESSION SET Session_Cached_Cursors=1;
Session altered.
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
4 END LOOP;
5 END;
6 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
101 200 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
設定了Session_Cached_Cursors=1後,語句只增加了1次解析
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
4 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where header_block>1000';
5 END LOOP;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6
SQL> /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
201 300 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
100 100 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block>:"SYS_B_0"
如果增加了1個語句,由於只能使用1個Session_Cached_Cursors,所以又增加了100次
SQL> ALTER SESSION SET Session_Cached_Cursors=2;
Session altered.
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
4 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where header_block>1000';
5 END LOOP;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
202 400 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
200 200 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block>:"SYS_B_0"
第二個SQL不能使用Session_Cached_Cursors
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
4 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where header_block>1000';
5 END LOOP;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
203 500 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
300 300 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block>:"SYS_B_0"
嘗試改為FORCE
SQL> ALTER SESSION SET CURSOR_SHARING=FORCE;
Session altered.
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
4 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where header_block>1000';
5 END LOOP;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
204 600 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
400 400 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block>:"SYS_B_0"
設定成FORCE依然不行,那實驗下為exact
SQL> ALTER SESSION SET CURSOR_SHARING=exact;
Session altered.
SQL> BEGIN
2 FOR i IN 1..100 LOOP
3 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1';
4 EXECUTE IMMEDIATE 'SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where header_block>1000';
5 END LOOP;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG7%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
205 700 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1
400 400 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block>:"SYS_B_0"
1 100 SELECT /*+FLAG7*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block>1000
SQL> DECLARE
2 ln_num NUMBER := 100;
3 BEGIN
4 FOR i IN 1..100 LOOP
5 EXECUTE IMMEDIATE 'SELECT /*+FLAG8*/SUM(HEADER_BLOCK) FROM T1';
6 EXECUTE IMMEDIATE 'SELECT /*+FLAG8*/SUM(HEADER_BLOCK) FROM T1 where header_block> :b' USING ln_num;
7 END LOOP;
8 END;
9 /
PL/SQL procedure successfully completed.
SQL> SELECT parse_calls,executions,sql_text
2 FROM V$SQLAREA
3 WHERE SQL_TEXT LIKE '%FLAG8%'
4 AND SQL_TEXT NOT LIKE '%sqlarea%'
5 AND sql_text NOT LIKE '%BEGIN%'
6 /
PARSE_CALLS EXECUTIONS SQL_TEXT
----------- ---------- --------------------------------------------------
1 100 SELECT /*+FLAG8*/SUM(HEADER_BLOCK) FROM T1 where h
eader_block> :b
1 100 SELECT /*+FLAG8*/SUM(HEADER_BLOCK) FROM T1
必須要使用繫結變數才能很好的使用sessin_cursor_cache
cursor_charing <> exact 時候,OUTLINE,STA不起作用
這個以前測試過,就不做測試了。不起作用的原因為,優化器根據沒有進行自動繫結變數的SQL去找OUTLINE,STA中的執行計劃,而OUTLINE,STA中儲存的執行計劃為進行繫結後的語句
總結一下如何使用這個後面 cusor_sharing
- 如果要使用similar,不要收集直方圖,但是沒直方圖,感覺還不如用force
- similar很耗記憶體,對於我們的一個省級中的應用,單例項,SQL AREA基本需要2G以上,RAC的話,每個例項幾乎都需要2G以上
- sessin_cursor_cache幾乎沒作用,可以不做設定。
- 呼叫工具OUTLINE,STA就別想用,唉,唯一的辦法只有該SQL,其他和執行計劃有關的引數最好別調整,副作用太大
- 再次看出繫結變數的重要性!!!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8242091/viewspace-584883/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 解決Pygame精靈會跳但不會走的問題GAM
- 實施專案問題管理的七步走(轉)
- 修改計算機名後導致Oracle無法訪問的問題修復計算機Oracle
- Oracle TNSListener服務啟動後自動停止問題Oracle
- oracle的時區問題Oracle
- oracle的監聽問題Oracle
- oracle 解鎖的問題Oracle
- lucene入門問題
- 如何解決銷售離職帶走客戶的問題?
- 走進Oracle世界Oracle
- Oracle delete資料後的釋放表空間問題的解決 --轉Oracledelete
- iOS 越獄後碰到的問題iOS
- Oracle 19C上線後可能出現的問題彙總(全)Oracle
- ORACLE碎片問題Oracle
- Oracle的SCN顯示問題Oracle
- oracle rename 的連帶問題Oracle
- oracle 鎖問題的解決Oracle
- Oracle MTS的相關問題Oracle
- 操作oracle出現的問題Oracle
- oracle 中使用like的問題Oracle
- 徵集對Oracle的問題 薦Oracle
- 轉:Oracle的時區問題Oracle
- oracle無法用oracle認證的問題Oracle
- Windows 系統安裝Oracle升級到9.2.0.8 後,exp問題WindowsOracle
- 關於jdon的ioc的入門問題
- 五眼想要 WhatsApp 的後門訪問APP
- Oracle Expdp匯出時定義任務名後終止退出的問題Oracle
- 主機名改名後oracle database control 無法啟動的問題OracleDatabase
- 32位升級到64位之後遷移oracle db遇到的問題Oracle
- 第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.3 題解:機器人走方格問題遞迴機器人
- TensorBoard啟動後No dashboards ...的問題ORB
- IOS9後網路的問題iOS
- Oracle常見問題一千問Oracle
- oracle 92 oem 錯誤的更改oracle sga後,導致instance無法啟動的問題解決Oracle
- 2022 SDC 議題 | 從後門到漏洞——智慧裝置私有協議中的安全問題協議
- 禁用 COOKIE 後如何訪問 SESSION 問題CookieSession
- oracle dblink問題Oracle
- Oracle IO問題解析Oracle