小解謂詞 access 與 filter
小解謂詞 access 與 filter
對這兩個謂詞以前的理解是:
access:和訪問表的方式有關,access標識訪問表的方式是索引。
filter:只起過濾的作用。
今天看到幾個explain 改變了我對這點的理解。上面的理解也對,但是不完整,
我理解的有些生硬。
SQL> create table t
2 as select rownum r,object_name
3 from dba_objects
4 /
Table created.
SQL> create index t_idx on t(r);
Index created.
SQL> execute dbms_stats.gather_table_stats(user,'t',cascade=>true)
PL/SQL procedure successfully completed.
SQL> set autotrace traceonly explain
SQL> select * from t
2 where r = 10000;
Execution Plan
----------------------------------------------------------
Plan hash value: 470836197
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("R"=10000)
使用的謂詞是access ,訪問的是索引,然後透過rowid 直接取出select結果。
SQL> select * from t
2 where r > 10000 and r < 50000
3 /
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 40001 | 1171K| 88 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| T | 40001 | 1171K| 88 (2)| 00:00:02 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("R"<50000 AND "R">10000)
使用的謂詞是filter 使用的是全表掃描,過濾掉不需要的行。
SQL> select r from t
2 where r > 10000
3 /
Execution Plan
----------------------------------------------------------
Plan hash value: 3163761342
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 55631 | 271K| 42 (3)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| T_IDX | 55631 | 271K| 42 (3)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("R">10000)
這裡的執行計劃,就有點意思了,使用的是索引掃描(index fast full scan),
但是沒有透過access 指出。可見oracle 決定使用索引掃描,並不一定要透過
access 來告訴我們。在這裡r 可以完全透過讀取索引來獲得所需要的列值,並且
需要檢索索引中的大部分key,所以oracle 決定使用index fast full scan,這種
訪問索引的方式會透過multiblocks read 方式讀取索引的 bocks,返回的結果集
是未經排序的,並且因為讀取了所以的index blocks ,所以需要對index blocks
中的index keys 進行過濾。
SQL> create table emp
2 as select employee_id,first_name,last_name
3 from hr.employees;
Table created.
SQL> create index emp_idx on emp(employee_id,last_name);
Index created.
SQL> exec dbms_stats.gather_table_stats(user,'emp',cascade=>true)
PL/SQL procedure successfully completed.
SQL> select employee_id,last_name
2 from emp
3 where employee_id < 200 and last_name = 'King'
4 /
Execution Plan
----------------------------------------------------------
Plan hash value: 3087982339
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 24 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| EMP_IDX | 2 | 24 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("LAST_NAME"='King' AND "EMPLOYEE_ID"<200)
filter("LAST_NAME"='King')
我上面這個例子也比較有意思,我們在前面建立了一個複合索引,並且在where 子句中
使用了索引中的列。oracle 會根據where 條件透過訪問複合索引中的列是否滿足employee_id < 200
如果滿足再根據條件filter 過濾出last_name = 'King' 的index Key。
小結:透過上面的列子,雖然例子不是很經典,但是我覺得已經可以說明。
1、如果oracle 決定使用 index 來獲得結果集,不需要使用access 謂詞告訴我們,我(oracle)使用了index.
2、透過index 訪問資料,也有可能需要用到filter 的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26110315/viewspace-730083/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【提示】filter 與access 的區別Filter
- 恕我直言你可能真的不會java第3篇:Stream的Filter與謂詞邏輯JavaFilter
- C++謂詞C++
- Partition 表掃描的過程,使用key作為謂詞與使用非key值做謂詞....
- Java 8謂詞鏈Java
- java8-謂詞(predicate)Java
- 原子謂詞公式和合式公式公式
- JavaWeb - 【Filter】敏感詞過濾JavaWebFilter
- 傳說中的“謂詞越界“場景
- SQL 改寫系列七:謂詞移動SQL
- SQL 改寫系列六:謂詞推導SQL
- 謂詞條件是is null走索引嗎?Null索引
- 執行計劃-4:謂詞的選擇時機與使用細節
- 使用謂詞(NSPredicate)來提高集合遍歷與過濾查詢的效率
- 【SQL】Oracle查詢轉換之謂詞推送SQLOracle
- C#2.0謂詞的簡單應用C#
- 優化擁有謂詞or的子查詢優化
- Oracle查詢轉換(四)連線謂詞推入Oracle
- 【GreatSQL最佳化器-02】索引和Sargable謂詞SQL索引
- CodeQL學習筆記(1)-QL語法(邏輯連線詞、量詞、聚合詞、謂詞和類)筆記
- CBO的查詢轉換(謂詞推入與子查詢展開(Subquery Unnesting))
- Oracle 執行計劃中access 和 filter的區別OracleFilter
- Oracle 12CR2查詢轉換之謂詞推送Oracle
- C++ 一元謂詞對應的lambda表示式C++
- 標準變成使謂詞(布林函式)返回true函式
- 小解http協議HTTP協議
- Android Toast小解AndroidAST
- 大資料SQL中的Join謂詞下推,真的那麼難懂?大資料SQL
- 第二十一篇:最佳謂詞函式 --- 函式物件函式物件
- 基於CBO優化器謂詞選擇率的計算方法優化
- repository 模式的小解模式
- 【大資料】SparkSql連線查詢中的謂詞下推處理(一)大資料SparkSQL
- 【大資料】SparkSql 連線查詢中的謂詞下推處理 (二)大資料SparkSQL
- 謂詞下推:計算和儲存分開進行分析是低效的?
- 【TUNE_ORACLE】列出SQL謂詞中需要建立索引的列SQL參考OracleSQL索引
- 基於CBO最佳化器謂詞選擇率的計算方法
- [20150610]sql的謂詞中使用函式.txtSQL函式
- 小解惑:查詢構造器與集合中的 get 方法