回答
我假設你想知道下面之間的性能差異:
WHERE foo IN ('a', 'b', 'c')
WHERE foo = 'a' OR foo = 'b' OR foo = 'c'
根據manual for MySQL如果值是常數IN
排序列表,然後使用二進制搜索。我會想象,OR
評估他們一個接一個沒有特定的順序。所以IN
在某些情況下速度更快。
要知道的最好方法是使用特定數據在數據庫上分析兩者,以查看哪個更快。
我試着用1000000行的MySQL。列索引時,性能沒有明顯差異 - 兩者幾乎都是即時的。使用
SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000);
1 row fetched in 0.0032 (1.2679 seconds)
SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000;
1 row fetched in 0.0026 (1.7385 seconds)
因此,在這種情況下,方法或慢約30%:當列沒有被索引我得到了這些結果。增加更多的術語會使差異更大。其他數據庫和其他數據的結果可能會有所不同。
如果優化器值得它的鹽,它們應該執行相同的操作。 – 2010-06-19 07:30:52
@inflagranti:不幸的是沒有優化器是完美的。優化器是非常複雜的程序,每個實現都有其優點和缺點。這就是爲什麼我說你應該介紹一個特定的實現。我想像'IN'方法的額外結構可以比一大堆可能相關的'OR'子句更容易優化。如果有一個'OR'方法更快的引擎,我會感到驚訝,但我並不感到有些時候OR更慢時並不感到驚訝。 – 2010-06-19 08:12:31
@MarkByers優化器不能總是用多個'OR'替代'IN'嗎? – mayu 2016-09-19 22:23:20
OR
(從可讀性的角度來看)是有意義的,當有較少的值進行比較時。 IN
尤其有用。當你有一個動態的來源,你想要比較值。
另一種替代方法是將JOIN
與臨時表一起使用。
我不認爲性能應該是一個問題,只要你有必要的索引。
找出最佳方法是查看執行計劃。
我試了一下甲骨文,這是完全一樣的。
CREATE TABLE performance_test AS (SELECT * FROM dba_objects);
SELECT * FROM performance_test
WHERE object_name IN ('DBMS_STANDARD', 'DBMS_REGISTRY', 'DBMS_LOB');
即使查詢使用IN
,執行計劃說,它使用OR
:
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 1416 | 163 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| PERFORMANCE_TEST | 8 | 1416 | 163 (2)| 00:00:02 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME"='DBMS_LOB' OR "OBJECT_NAME"='DBMS_REGISTRY' OR
"OBJECT_NAME"='DBMS_STANDARD')
如果您有超過3個正在測試的值,Oracle會發生什麼情況?你知道Oracle是否無法像MySQL一樣執行相同的二分搜索優化,或者它是否在這兩種情況下都能執行? – 2010-06-19 08:59:44
@Mark Byers:我用10個值嘗試了相同的查詢,結果仍然相同。請注意,優化器按字母順序使用了我的值。如果Oracle對該過濾器進行了一些內部優化,我不會感到驚訝... – 2010-06-19 09:49:12
Oracle也有一個'INLIST ITERATOR'操作,它會選擇是否有可用的索引。不過,當我試用它時,'IN'和'OR'結果都是相同的執行計劃。 – 2010-06-19 15:47:04
我認爲甲骨文很聰明,可以將效率較低的一方(無論是哪一方)轉換成另一方。所以我認爲答案應該取決於每個的可讀性(我認爲IN
明顯勝出)
OR運算符需要比IN構造更復雜的評估過程,因爲它允許許多條件,不僅等於像在。
這裏是一個你可以使用的但是與IN不兼容的: 更大。大於或等於,小於,小於或等於,LIKE和一些更像oracle的REGEXP_LIKE。 另外考慮到條件可能並不總是比較相同的值。
對於查詢優化器來說,更容易管理IN運算符,因爲它只是一個構造,它在多個條件中使用=運算符定義OR運算符的值相同。如果使用OR運算符,優化程序可能不會認爲您總是對相同的值使用=運算符,並且如果它沒有執行更深入和更復雜的闡述,則可能會排除僅可能存在=所有相關條件下的相同值的運算符,並隨後排除優化的搜索方法(如已提及的二進制搜索)。
[編輯] 可能優化器可能不會實現優化的IN評估過程,但這並不排除它可能發生的一次(數據庫版本升級)。因此,如果您使用優化精化的OR運算符將不會用於您的情況。
我在大量的OR(350)中做了一個SQL查詢。 Postgres做它437.80ms。
現在使用IN:
23.18ms
這不完全相同,因爲你已經使用了IN子句的子查詢。 – gliljas 2017-01-16 16:35:52
- 1. IN vs = where Where子句
- 2. SQL Server Where子句使用In()vs Wildcard
- 3. SQL - Concat與IN中的where子句
- 4. SQL IN操作符的WHERE子句
- 5. SQL Where子句
- 6. Where子句中SQL
- 7. NOT IN WHERE子句錯誤
- 8. jhat OQL AND in where子句
- 9. INSERT INTO與WHERE IN子句
- 10. WHERE子句VS使用JOIN
- 11. Android的sqlite中的WHERE IN子句?
- 12. MySQL的UNION VS IN子句
- 13. SELECT WHERE中的條件NOT IN子句
- 14. Where子句包括IN和NOT IN
- 15. ORACLE中的SQL Where子句
- 16. SQL:在 'where子句'
- 17. SQL語句WHERE子句
- 18. 保留SQL中的WHERE IN()子句的順序SELECT
- 19. SQL中的/否則Where Where子句
- 20. T SQL WHERE子句
- 21. SQL WHERE IN子句中包含具有ID的對象列表?
- 22. WHERE子句中的HIVE SQL子查詢
- 23. SQL子查詢(Where In)
- 24. SQL where子句子查詢
- 25. SQL Server WHERE子句
- 26. SQL - where子句NULL
- 27. SQL Concat Where子句
- 28. SQL 2 where子句
- 29. SQL DateDifference在where子句中
- 30. SQL語句中的WHERE子句陳述
我的第一個猜想是,或者執行更好,除非SQL引擎轉換成或幕後。你見過這兩個查詢計劃嗎? – Raj 2010-06-19 07:19:21
[MYSQL OR vs IN性能]可能的重複(http://stackoverflow.com/questions/782915/mysql-or-vs-in-performance) – 2016-11-08 08:30:49