2015-12-01 62 views
1

因此,下面是兩條返回相同結果的語句。Oracle:=和in有什麼區別?

SELECT * FROM USERS WHERE ID = 1; 
----------------------- 
SELECT * FROM USER WHERE ID IN (1); 

有時更容易產生從單個項目的第二個查詢,以增加額外的項目列表的選項。

在Oracle中使用單個項目列表是否存在固有風險?是否可能導致性能問題?

+0

in運算符只是語法糖(在子查詢未使用的情況下) – ibre5041

+0

AFIAK在運算符中有一些內部限制數字段。在這種限制的情況下,優化器甚至不會看到這個運算符,這將查詢重寫爲分離序列。 – ibre5041

回答

5

您顯示的兩個查詢除語法外沒有任何區別。比較解釋計劃:

查詢1:

SQL> EXPLAIN PLAN FOR SELECT * FROM dual WHERE dummy = 'X'; 

Explained. 

SQL> SELECT * FROM TABLE(dbms_xplan.display); 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------- 
Plan hash value: 272002086 

-------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  1 |  2 |  2 (0)| 00:00:01 | 
|* 1 | TABLE ACCESS FULL| DUAL |  1 |  2 |  2 (0)| 00:00:01 | 
-------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------- 

    1 - filter("DUMMY"='X') 

13 rows selected. 

問題2:

SQL> EXPLAIN PLAN FOR SELECT * FROM dual WHERE dummy IN 'X'; 

Explained. 

SQL> SELECT * FROM TABLE(dbms_xplan.display); 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------- 
Plan hash value: 272002086 

-------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  1 |  2 |  2 (0)| 00:00:01 | 
|* 1 | TABLE ACCESS FULL| DUAL |  1 |  2 |  2 (0)| 00:00:01 | 
-------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------- 

    1 - filter("DUMMY"='X') 

13 rows selected. 

在這兩個查詢,內部應用的濾波器是濾波器( 「虛擬」= 'X')

然而,當你有多個值的詮釋,他IN列表,則Oracle在內部解釋爲多個OR條件。

IN列表

SQL> EXPLAIN PLAN FOR SELECT * FROM dual WHERE dummy IN ('X', 'Y', 'Z'); 

Explained. 

SQL> SELECT * FROM TABLE(dbms_xplan.display); 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------- 
Plan hash value: 272002086 

-------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  1 |  2 |  2 (0)| 00:00:01 | 
|* 1 | TABLE ACCESS FULL| DUAL |  1 |  2 |  2 (0)| 00:00:01 | 
-------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------- 

    1 - filter("DUMMY"='X' OR "DUMMY"='Y' OR "DUMMY"='Z') 

13 rows selected. 

你可以看到Oracle在內部將其解釋爲過濾器( 「虛擬」= 'X' 或 「虛擬」= 'Y' 或 「僞」= 'Z' )

+0

所以我認爲你說的是​​使用單個項目列表很少或沒有開銷,並且Oracle在運行之前會清理查詢?在IN列表中有多個值的 – AJFaraday

+0

只會增加OR條件,這意味着Oracle需要查找更多符合OR條件的數據。對於單個值,根本沒有差別。 –