直方圖;繫結變數窺探;自適應遊標
搭建環境
構建一個表 CREATE TABLE TEST2 AS SELECT * FROM DBA_OBJECTS; UPDATE SET OBJECT_ID = 11111 WHERE ROWNUM <=50000; 建立索引: CREATE INDEX IND_TEST2_OBJECT_ID ON TEST2(OBJECT_ID); 收集統計資訊,不收集直方圖 EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'SCOTT',TABNAME=>'TEST2',ESTIMATE_PERCENT=>100,cascade=>true,method_opt => 'for all columns size 1');
SQL> SELECT OBJECT_ID FROM TEST2 WHERE OBJECT_NAME = 'TEST';
OBJECT_ID
----------
52694
毋庸置疑index range scan
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=11111;
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=52694;
收集直方圖
BEGIN DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SCOTT', tabname => 'TEST2', estimate_percent => 100, method_opt => 'for all columns size skewonly', no_invalidate => FALSE, degree => 1, cascade => TRUE); END; /
全表掃描
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=11111;
index range scan
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=52694;
9i,10g
alter system flush shared_pool;
var a number;
exec :a := 52694;
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> select sql_id,child_number from v$sql where sql_text like 'SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a%';
SQL_ID CHILD_NUMBER
------------- ------------
22gd2utvtttmj 0
SQL> select * from table(dbms_xplan.display_cursor('22gd2utvtttmj',0,'advanced peeked_binds'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 22gd2utvtttmj, child number 0
-------------------------------------
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a
Plan hash value: 3600962442
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX RANGE SCAN| IND_TEST2_OBJECT_ID | 1 | 5 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
2 - SEL$1 / [email protected]$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "TEST2"@"SEL$1" ("TEST2"."OBJECT_ID"))
END_OUTLINE_DATA
*/
Peeked Binds (identified by position):
--------------------------------------
1 - :A (NUMBER): 52694
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=:A)
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - (#keys=0) COUNT(*)[22]
==================================================================================================================
exec :a := 11111;
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> select sql_id,child_number from v$sql where sql_text like 'SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a%';
SQL_ID CHILD_NUMBER
------------- ------------
22gd2utvtttmj 0
SQL> select * from table(dbms_xplan.display_cursor('22gd2utvtttmj',0,'advanced peeked_binds'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 22gd2utvtttmj, child number 0
-------------------------------------
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a
Plan hash value: 3600962442
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX RANGE SCAN| IND_TEST2_OBJECT_ID | 1 | 5 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
2 - SEL$1 / [email protected]$1
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.1')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX(@"SEL$1" "TEST2"@"SEL$1" ("TEST2"."OBJECT_ID"))
END_OUTLINE_DATA
*/
Peeked Binds (identified by position):
--------------------------------------
1 - :A (NUMBER): 52694
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=:A)
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - (#keys=0) COUNT(*)[22]
從上面可以發現,由於繫結變數只有在硬解析的時候才回去“窺探”,所以硬解析時候窺探的繫結變數的值就決定了整個執行計劃,即使發生改變oracle的也不管。這個就比較坑爹了。11g
SQL> var a number;
SQL> exec :a := 52694;
PL/SQL procedure successfully completed.
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> select * from table(dbms_xplan.display_cursor(null,null,'advanced peeked_binds'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 67wpp1xx1jsb4, child number 0
-------------------------------------
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a
Plan hash value: 3600962442
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX RANGE SCAN| IND_TEST2_OBJECT_ID | 1 | 5 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
2 - SEL$1 / [email protected]$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(@"SEL$1" "TEST2"@"SEL$1" ("TEST2"."OBJECT_ID"))
END_OUTLINE_DATA
*/
Peeked Binds (identified by position):
--------------------------------------
1 - :A (NUMBER): 52694
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=:A)
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - (#keys=0) COUNT(*)[22]
==============================================================================
SQL> exec :a := 11111;
PL/SQL procedure successfully completed.
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> select sql_id,child_number from v$sql where sql_text like 'SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a%';
SQL_ID CHILD_NUMBER
------------- ------------
22gd2utvtttmj 0
22gd2utvtttmj 1
22gd2utvtttmj 2
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
50000
SQL> select * from table(dbms_xplan.display_cursor(null,null,'advanced peeked_binds'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 22gd2utvtttmj, child number 2
-------------------------------------
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a
Plan hash value: 1970853342
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 48 (100)| |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX FAST FULL SCAN| IND_TEST2_OBJECT_ID | 49956 | 243K| 48 (3)| 00:00:01 |
---------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
2 - SEL$1 / [email protected]$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_FFS(@"SEL$1" "TEST2"@"SEL$1" ("TEST2"."OBJECT_ID"))
END_OUTLINE_DATA
*/
Peeked Binds (identified by position):
--------------------------------------
1 - :A (NUMBER): 11111
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("OBJECT_ID"=:A)
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - (#keys=0) COUNT(*)[22]
49 rows selected.
SQL> exec :a := 52694;
PL/SQL procedure successfully completed.
SQL> SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a;
COUNT(*)
----------
1
SQL> select * from table(dbms_xplan.display_cursor(null,null,'advanced peeked_binds'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 22gd2utvtttmj, child number 1
-------------------------------------
SELECT count(*) FROM TEST2 WHERE OBJECT_ID=:a
Plan hash value: 3600962442
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)| |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
|* 2 | INDEX RANGE SCAN| IND_TEST2_OBJECT_ID | 1 | 5 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$1
2 - SEL$1 / [email protected]$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(@"SEL$1" "TEST2"@"SEL$1" ("TEST2"."OBJECT_ID"))
END_OUTLINE_DATA
*/
Peeked Binds (identified by position):
--------------------------------------
1 - :A (NUMBER): 75819
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=:A)
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - (#keys=0) COUNT(*)[22]
從上面可以看出來,11g之後,oracle引入自適應遊標,oracle會根據繫結變數值得改變而改變執行計劃了。這才是我們需要的。
相關推薦
直方圖;繫結變數窺探;自適應遊標
搭建環境 構建一個表 CREATE TABLE TEST2 AS SELECT * FROM DBA_OBJECTS; UPDATE SET OBJECT_ID = 11111 WHERE ROWNUM <=50000; 建立索引: CREATE INDEX IND
Oracle 繫結變數窺探
Bind Peeking是Oracle 9i中引入的新特性,一直持續到Oracle 10g R2。它的作用就是在SQL語句硬分析的時候,檢視一下當前SQL謂詞的值 ,以便生成最佳的執行計劃。而在oracle 9i之前的版本中,Oracle 只根據統計資訊來做出執行計劃。
SQL Profiles的force_match引數在不改變程式碼的情況下解決沒有使用繫結變數的問題
How To Use SQL Profiles for Queries Using Different Literals Using the Force_Match Parameter of DBMS_SQLTUNE.ACCEPT_SQL_PROFILE (Doc ID 1253696.1)
jQuery on() 方法 為選定已存在元素和未來元素繫結標準事件和自定義事件
很有必要說說jQuery的on方法,這個方法存在大乾坤大奧祕,主要注意兩點: 1、為已存在元素和未來元素(動態新增元素)繫結處理函式。 2、自定義一個非標準的事件並繫結處理函式。 定義和用法 on() 方法在被選元素及子元素上新增一個或多個事件處理程式。 自 jQuery 版本 1.7 起,on()
檢視oracle中未使用繫結變數的sql語句
資料庫版本:11.2.0.4 查詢語句: with force_mathces as (select l.force_matching_signature mathces, max(l.sql_id || l.child_number) max_sql_
Nginx 內建繫結變數
Nginx作為一個成熟、久經考驗的負載均衡軟體,與其提供豐富、完整的內建變數是分不開的,它極大增加了對Nginx網路行為的控制細度。這些變數大部分都是在請求進入時解析的,並把他們快取到請求cycle中,方便下一次獲取使用。首先來看看Nginx對都開放了那些API。 參看下表
mybatis批量分批次插入oracle資料庫,報ORA-01745: 無效的主機/繫結變數名...
方法一:迴圈呼叫插入單條記錄的方法,效率真心讓人捉急 (3萬條資料,快三分鐘) public int saveGwghidlist1(List<Gwghid> list) { int xh=0; dele
angular/ionic中對img、iframe等的src進行動態繫結變數的問題解決
例如以下程式碼: 對應的html頁面中是這樣:<iframe class=“filling” [src] = “iframe”> 在這裡直接對src進行動態繫結變數就會出現:unsafe value used in a resource URL co
spring 中@ModelAttribute繫結變數中文亂碼的解決辦法
網上找了一些方法: 方法一 在專案的web.xml中配置spring的Character Encoding Filter <!-- Servlet Encoding Start --> <filter> <filter
python cx_oracle 繫結變數
insert into tlcb_collect_f5 values(:stime,:virtual_servers,:default_pool_name,:ipaddr,:port,:AVAILABILITY_STATUS,:ENABLED_STATUS,:POOL_MEMBER_STATUS);
powershell指令碼,命令列引數傳值,並繫結變數的例子
這是小技巧文章,所以文章不長。但原創唯一,非常重要。我搜了下,還真沒有人發 powershell怎樣 【命令列 引數 繫結】,所以我決定寫成部落格。 搜尋關鍵字如下: powershell 命令列 引數 繫結 powershell 傳入 引數 powershell 傳遞 引數 p
oracle動態sql以及繫結變數
實現動態SQL有兩種方式:DBMS_SQL和本地動態SQL(EXECUTE IMMEIDATE) 。 oracle從8代開始就提供了新的執行動態sql的功能:execute immeidate v_sql using *** into ***; 本地動態
sqlplus之使用繫結變數
oracle將已解析、已編譯的SQL連同其他內容儲存在共享池(shared pool)中,這是系統全域性區(System Global Area,SGA)中一個非常重要的共享記憶體結構.繫結變數(bind variable)是查詢中的一個佔位符。例如,要獲取員工編號7369的
android6.0下SETTING_VERSION無法繫結變數
在android6.0 RK3288這個平臺,碰到這樣的一個問題,在帶有Android.mk的目錄下執行命令mm -B時報錯: ./prebuilts/sdk/tools/jack-admin: line 37:SETTING_VERSION: unbound varia
關於繫結變數關閉的情況,Oracle是如何工作的?
關於如果繫結變數窺探被關閉了,oracle 會怎麼處理的呢?是每次都硬解析還是這樣處理? 首先介紹下繫結變數窺探: 使用SQL首次執行時的值來生成執行計劃。後續再次執行該SQL語句則使用首次執行計劃來執行。 測試版本:Oracle 12.1.0.2
oracle筆記--case的使用和繫結變數
oracle裡的case功能非常強大, 簡單的用法: select CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END from student; 還沒有當做預處理去使用 select
ORACLE 繫結變數用法總結
之前對ORACLE中的變數一直沒個太清楚的認識,比如說使用:、&、&&、DEIFINE、VARIABLE……等等。今天正好閒下來,上網搜了搜相關的文章,彙總了一下,貼在這裡,方便學習。 ================================
oracle開發過程中儘量使用繫結變數
在儲存過程或者java程式使用sql的過程中,儘量使用繫結變數。否則硬解析太多,比較拖效能。 下面查詢只是空格多了幾個。 SQL> select * from ml_1234 where a
動態建立一組按鈕,併為其繫結變數引數事件方法
做專案時,遇到一個比較奇怪的需求,需要用highChart作圖,但是由於橫座標是公司的部分職級的人員,且人員數目較多,這樣就會造成作出來的圖好長, 在有限的螢幕上顯示不全。於是客戶要求,可以將所有人員根
phpcms手機門戶二開實現繫結任意欄目和自定義模板
用phpcms的自帶的手機站模組開發手機站,你可能碰到這樣那樣的問題,比如一下: (1)phpcms手機站無法繫結單頁面 (2)seo無法呼叫關鍵詞或者網站欄目 (3)繫結欄目雖然有排序卻不起作用 (4)如果只繫結父欄目卻無法呼叫列表,還得必須繫結子欄目 (5)欄目