讓我們來完成如下實驗:
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options
SQL> create table larry_test (v1 number,v2 number);
Table created.
SQL> insert into larry_test values(100,1);
1 row created.
SQL> insert into larry_test values(101,2);
1 row created.
SQL> insert into larry_test values(103,1);
1 row created.
SQL> commit;
Commit complete.
SQL> set autotrace on explain
SQL> select * from larry_test where v2 in (1,2);
Execution Plan
———————————————————-
Plan hash value: 2936416851
——————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————–
| 0 | SELECT STATEMENT | | 3 | 78 | 15 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| LARRY_TEST | 3 | 78 | 15 (0)| 00:00:01 |
——————————————————————————–
Predicate Information (identified by operation id):
—————————————————
1 – filter(“V2″=1 OR “V2″=2)
Note
—–
– dynamic sampling used for this statement
SQL> select * from larry_test where v2 =1 or v2=2;
Execution Plan
———————————————————-
Plan hash value: 2936416851
——————————————————————————–
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
——————————————————————————–
| 0 | SELECT STATEMENT | | 3 | 78 | 15 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| LARRY_TEST | 3 | 78 | 15 (0)| 00:00:01 |
——————————————————————————–
Predicate Information (identified by operation id):
—————————————————
1 – filter(“V2″=1 OR “V2″=2)
Note
—–
– dynamic sampling used for this statement
通過上述實驗,檢視執行計劃(粗體字的部分),我們不難發現執行IN的SQL在被ORACLE分析後,其過濾謂詞(filter predicate)已經被轉換稱為了(“V2″=1 OR “V2″=2)和使用OR關鍵字的SQL完全相同!
所以我們的結論就是:IN和OR沒有伯仲之分,效能是相同的!
——————–附加
ORACLE確實是在不斷進步的,這個實驗在10G中完成,顯示的執行計劃等都完成了格式化,非常整齊好看。雖然在9I中結果是相同的,但是執行計劃如下顯示:
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 TABLE ACCESS (FULL) OF `LARRY_TEST`
不十分好看,且沒有主動顯示過濾謂詞。我只能通過EXPLAIN PLAN FOR命令得到執行計劃,然後在到PLAN_TABLE中查詢確認。
歡迎這種進步 -:)
附贈關於Autotrace幾個常用選項的說明:
SET AUTOTRACE ON EXPLAIN —— AUTOTRACE只顯示優化器執行路徑報告
SET AUTOTRACE ON —————– 包含執行計劃和統計資訊
SET AUTOTRACE TRACEONLY —— 同set autotrace on,但是不顯示查詢輸出