2009-11-09 39 views
3

想象有一個SQL,並在該SP的某些部分,有WHERE子句查找兩個ID;SQL和性能問題IN和OR

... WHERE ID IN(123,1245)

,而不是使用IN,如果我用OR;

我會得到什麼或鬆動。或者他們兩個是平等的?

回答

2

Oracle,SQL ServerMySQL將爲這兩個查詢生成相同的計劃。

如果有問題的字段沒有編入索引,這只是一個簡單的過濾器。

如果該字段被索引和索引尋求由優化程序選擇:

  • Oracle使用INLIST ITERATOR
  • SQL Server使用CONSTANT SCAN
  • MySQL使用range訪問方法

PostgreSQL生成名義上不同的計劃:OR在第一種情況下有兩個索引條件,在第二種情況下有一個索引條件ANY(123, 1245):INTEGER[]

然而,這在實踐中也沒有差異。

請注意,這兩個查詢總是對兩個值都使用相同的訪問方法,而使用不同的訪問方法可能更有效。

一些查詢可能從此改寫了他們作爲一個聯盟中受益:

SELECT * 
FROM mytable 
WHERE id = 123 
     AND … 
UNION ALL 
SELECT * 
FROM mytable 
WHERE id = 1245 
     AND … 

視域選擇性,這可能(也可能不會)產生不同的執行計劃的兩個查詢,這可能(也可能不會)獲得效率。

1

這些在邏輯上是相同的......兩者(假設你的ID列是PK)將執行索引查找。

一個簡單的方法來了解SQL如何處理這樣的查詢是單擊SSMS工具欄上的按鈕,所謂的「顯示估計的執行計劃」的「執行」按鈕的右側。執行時還可以選擇顯示實際計劃。無論哪種方式,這將讓你看到SQL Server如何將查詢分解成更小的部分。這是調整查詢中最重要的工具。

1

在這種情況下,臨界點不是使用IN或OR,而是使用適當索引的ID字段。

2

回到我這幾年在學校:我被教導的IN(... ..)表達在一包或陳述,SQL執行之前分解。

它接縫它只是一個更全面的代碼。

+0

邏輯上,你是完全正確的。但它可能會導致不同的執行計劃。 – Thorsten 2009-11-09 13:26:14

+0

@IronGoofy:完全沒有。在Oracle 8中,現代數據庫應該可以很好地處理它。 – 2009-11-09 22:39:57

3

有一個excellent article討論了類似的問題(而不是在與EXISTS與LEFT JOIN)。基本上,它表明它們非常相似,而且不同的優化器處理這些問題的效果非常好。

我期望優化器處理您提到的兩個備選方案會導致類似的執行計劃。如果存在差異,請使用EXPLAIN PLAN進行檢查。

0

他們是相同的,幾乎所有的數據庫系統(甲骨文,SQL服務器,MySQL的)的新版本 - 優化的IN轉換爲一系列的OR。您可以查看特定版本的執行計劃以查看它。

0

取決於實施。在大多數RDBMS的IN和OR語句中,它們的處理方式是相同的(因爲它們在邏輯上是相同的),但少數幾個包含優化,可以更好地處理它。

MySQL的實例確實含有優化它通常能夠執行IN clauses as a range scan

0

大多數企業級關係數據庫來分析的查詢執行計劃的能力。您應該使用此功能比較兩個變體的計劃。這是確切知道發生了什麼的最佳方式。