[20121231]給sql打補丁.txt
[20121231]給sql打補丁.txt
11G有一個快速的方法改寫sql執行計劃,加入hint來改變和穩定執行計劃。在連結
http://space.itpub.net/267265/viewspace-721817
我提到11G ACS的問題,可以透過加入提示/*+ BIND_AWARE */ 來解決:
拿這個例子來說明:
1.建立測試環境:
--可以發現ID2建立的直方圖是FREQUENCY直方圖。
--可以看出ID2分佈不均勻,如果查詢id2=100,最好的執行計劃是全表掃描。
--如果id2=100依舊使用索引掃描,效率肯定不好,11G的ACS就是用來解決這個問題,但是如果id2=:a (a=100)的執行次數很少,
--執行計劃一直會使用索引,無法達到預期的效果,這樣透過sql profile,SPM等可以加入提示來提高直接計劃,我這裡使用
--給sql打補丁的方式來解決這個問題.
exec sys.dbms_sqldiag_internal.i_create_patch (sql_text => 'Select * from t1 where id2= :a', hint_text => 'BIND_AWARE', name => 'patch_01yvuvyfm4fhb');
--注意:我修改select的第一個字母大寫。必須以sys使用者執行。
--回到原來的回話:
--即使你sql語句全部換成大寫,該補丁依舊有效。但是如果寫成這樣(就是有comment),該補丁就不行了。
SelecT /*+ aaaa */ * from t1 where id2= :a;
11G有一個快速的方法改寫sql執行計劃,加入hint來改變和穩定執行計劃。在連結
http://space.itpub.net/267265/viewspace-721817
我提到11G ACS的問題,可以透過加入提示/*+ BIND_AWARE */ 來解決:
拿這個例子來說明:
1.建立測試環境:
SQL> select * from v$version where rownum<=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
SQL> CREATE TABLE t1 AS
SELECT ROWNUM id1,FLOOR(SQRT(ROWNUM)) id2 ,'test' NAME FROM DUAL CONNECT BY LEVEL<=9999;
SQL> insert into t1 select rownum+9999,100 ,'test' NAME FROM DUAL CONNECT BY LEVEL<=9999;
SQL> create index i_t1_id2 on t1(id2);
Index created.
BEGIN
SYS.DBMS_STATS.GATHER_TABLE_STATS (
OwnName => user
,TabName => 'T1'
,Estimate_Percent => NULL
,Method_Opt => 'FOR COLUMNS ID2 SIZE 254 for all columns size 1'
,Degree => 4
,Cascade => TRUE
,No_Invalidate => TRUE);
END;
/
SQL> column low_value format a10
SQL> column high_value format a10
SQL> column data_type format a10
SQL> select column_name,data_type,num_distinct,low_value,high_value,num_buckets,histogram from dba_tab_cols where wner=user and table_name='T1';
COLUMN_NAME DATA_TYPE NUM_DISTINCT LOW_VALUE HIGH_VALUE NUM_BUCKETS HISTOGRAM
------------------------------ ---------- ------------ ---------- ---------- ----------- ---------------
ID1 NUMBER 19998 C102 C3026463 1 NONE
ID2 NUMBER 100 C102 C202 100 FREQUENCY
NAME CHAR 1 74657374 74657374 1 NONE
SQL>
--可以發現ID2建立的直方圖是FREQUENCY直方圖。
SQL> column ENDPOINT_ACTUAL_VALUE format a10
SQL> column COLUMN_NAME format a10
SQL> column owner format a10
SQL> column table_name format a10
SQL> select * from dba_tab_histograms where wner=user and table_name='T1' and column_name='ID2';
OWNER TABLE_NAME COLUMN_NAM ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_A
---------- ---------- ---------- --------------- -------------- ----------
SCOTT T1 ID2 3 1
SCOTT T1 ID2 8 2
SCOTT T1 ID2 15 3
SCOTT T1 ID2 24 4
SCOTT T1 ID2 35 5
SCOTT T1 ID2 48 6
SCOTT T1 ID2 63 7
SCOTT T1 ID2 80 8
SCOTT T1 ID2 99 9
SCOTT T1 ID2 120 10
....
SCOTT T1 ID2 7920 88
SCOTT T1 ID2 8099 89
SCOTT T1 ID2 8280 90
SCOTT T1 ID2 8463 91
SCOTT T1 ID2 8648 92
SCOTT T1 ID2 8835 93
SCOTT T1 ID2 9024 94
SCOTT T1 ID2 9215 95
SCOTT T1 ID2 9408 96
SCOTT T1 ID2 9603 97
SCOTT T1 ID2 9800 98
SCOTT T1 ID2 9999 99
SCOTT T1 ID2 19998 100
100 rows selected.
--可以看出ID2分佈不均勻,如果查詢id2=100,最好的執行計劃是全表掃描。
variable a number;
exec :a := 42;
select * from t1 where id2= :a;
SQL> @dpc '' ;
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID 01yvuvyfm4fhb, child number 0
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3984699272
----------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 2 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 85 | 2 (0)|
|* 2 | INDEX RANGE SCAN | I_T1_ID2 | 85 | 1 (0)|
----------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
1 - (NUMBER): 42
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID2"=:A)
Note
-----
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system level
30 rows selected.
--如果id2=100依舊使用索引掃描,效率肯定不好,11G的ACS就是用來解決這個問題,但是如果id2=:a (a=100)的執行次數很少,
--執行計劃一直會使用索引,無法達到預期的效果,這樣透過sql profile,SPM等可以加入提示來提高直接計劃,我這裡使用
--給sql打補丁的方式來解決這個問題.
exec sys.dbms_sqldiag_internal.i_create_patch (sql_text => 'Select * from t1 where id2= :a', hint_text => 'BIND_AWARE', name => 'patch_01yvuvyfm4fhb');
--注意:我修改select的第一個字母大寫。必須以sys使用者執行。
--回到原來的回話:
SQL> exec :a := 42;
PL/SQL procedure successfully completed.
SQL> select * from t1 where id2= :a;
SQL> @dpc ''
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
SQL_ID 01yvuvyfm4fhb, child number 0
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3984699272
----------------------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 2 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 85 | 2 (0)|
|* 2 | INDEX RANGE SCAN | I_T1_ID2 | 85 | 1 (0)|
----------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
1 - (NUMBER): 42
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID2"=:A)
Note
-----
- SQL patch "patch_01yvuvyfm4fhb" used for this statement
SQL> exec :a := 100;
PL/SQL procedure successfully completed.
SQL> @dpc ''
PLAN_TABLE_OUTPUT
-------------------------------------------------------------
SQL_ID 01yvuvyfm4fhb, child number 1
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3617692013
--------------------------------------------------------
| Id | Operation | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------
| 0 | SELECT STATEMENT | | | 17 (100)|
|* 1 | TABLE ACCESS FULL| T1 | 9999 | 17 (6)|
--------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
1 - (NUMBER): 100
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID2"=:A)
Note
-----
- SQL patch "patch_01yvuvyfm4fhb" used for this statement
--即使你sql語句全部換成大寫,該補丁依舊有效。但是如果寫成這樣(就是有comment),該補丁就不行了。
SelecT /*+ aaaa */ * from t1 where id2= :a;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-751900/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用OPatch給Oracle打補丁Oracle
- 給Oracle資料庫打補丁(轉)Oracle資料庫
- [202021127]sql打補丁問題.txtSQL
- [20220329]19c sql語句打補丁.txtSQL
- [20210929]sql打補丁使用rule提示問題.txtSQL
- 給oracle打Patch 9352237補丁Oracle
- 給HP-UX作業系統打補丁UX作業系統
- [20220330]編寫sql打補丁的指令碼.txtSQL指令碼
- 【UP_ORACLE】如何給Oracle DG打補丁(二)備庫安裝補丁步驟Oracle
- 【UP_ORACLE】如何給Oracle DG打補丁(三)主庫安裝補丁步驟Oracle
- 安裝oraInventory和使用opatch給Oracle打補丁AIOracle
- zt_使用opatch給oracle打補丁patch_bugOracle
- Torvalds給Linux核心打補丁抵禦病毒(轉)Linux
- [20201126]使用cursor_sharing_exact與給sql打補丁2.txtSQL
- [20201126]使用cursor_sharing_exact與給sql打補丁3.txtSQL
- oracle打補丁回顧Oracle
- Oracle EBS中打補丁Oracle
- 聊聊兩種給Grid Infrastructure打補丁的方法(上)ASTStruct
- 聊聊兩種給Grid Infrastructure打補丁的方法(下)ASTStruct
- 【UP_ORACLE】如何給Oracle DG打補丁(一)整體思路Oracle
- Linux檔案打補丁Linux
- SAP打補丁(Tcode:SPAM)
- weblogic的版本及打補丁Web
- ORACLE打補丁的方法和案例Oracle
- ORACLE11G DG打補丁Oracle
- opatch 工具打補丁使用說明
- Oracle資料庫打補丁方法Oracle資料庫
- oracle 小補丁能全部打嗎?Oracle
- 批處理打補丁的方法
- 給oracle 10.2.0.4.0 打em補丁8350262執行步驟Oracle
- 網管必讀教會使用者自己給系統打補丁(轉)
- 到底打還是不打補丁:安裝第三方補丁(轉)
- windows 打補丁後網路異常Windows
- Windows 10打個補丁 Office歇菜了Windows
- 【opatch】Oracle打補丁工具opatch簡介Oracle
- 在windows上打Oracle的CPU補丁WindowsOracle
- SQL Server最新安全補丁SQLServer
- Oracle RAC 19.3打19.5.1 RU補丁Oracle