有同事問我,在ORACLE的SQL執行中IN和OR誰更高效呢?
    讓我們來完成如下實驗:
   
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – 64bit Production
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中結果是相同的,但是執行計劃如下顯示:
  

Execution Plan
———————————————————-
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF `LARRY_TEST`

    不十分好看,且沒有主動顯示過濾謂詞。我只能通過EXPLAIN PLAN FOR命令得到執行計劃,然後在到PLAN_TABLE中查詢確認。  
    歡迎這種進步 -:)
    附贈關於Autotrace幾個常用選項的說明:

    SET AUTOTRACE OFF —————- 不生成AUTOTRACE 報告,這是預設模式
    SET AUTOTRACE ON EXPLAIN —— AUTOTRACE只顯示優化器執行路徑報告
    SET AUTOTRACE ON —————– 包含執行計劃和統計資訊
    SET AUTOTRACE ON STATISTICS — 只顯示執行統計資訊
    SET AUTOTRACE TRACEONLY —— 同set autotrace on,但是不顯示查詢輸出