2011-03-10 91 views
25

我使用MySQL 5.1中,我有一個查詢的大致形式:EXISTS比COUNT(*)> 0更有效嗎?

select count(*) from mytable where a = "foo" and b = "bar"; 

在我的程序,它檢查的唯一的事情是,這是否是零或非零。如果我把它轉換成:

select exists(select * from mytable where a = "foo" and b = "bar"); 

是MySQL的智能足以停止搜索時,它擊中第一個?還是有其他方式與MySQL溝通,我的意圖是簡單地找出是否有任何記錄符合此條件,並且我不需要精確計數?

+5

嘗試解釋這兩個查詢,你應該得到答案。您可以發佈解釋輸出,並且ppl將幫助您解碼。 – Zimbabao 2011-03-10 19:19:24

+0

MySQL知道優化'COUNT(*)> 0'是極不可能的! – Gabe 2011-03-10 19:19:40

+4

ANSI標準說EXISTS更好,因爲它不應該遍歷或評估超出行的「存在」http://stackoverflow.com/questions/3271455/whats-the-best-to-check-if-item-exist - 或 - 選擇countidor存在/ 3271464#3271464 – gbn 2011-03-10 19:21:34

回答

26

是的,當使用Exists函數返回一行時,MySQL(確實是所有數據庫系統,據我所知)將停止處理。

你可以閱讀更多的MySQL文檔: If a subquery returns any rows at all, EXISTS subquery is TRUE.

+0

我不確定SQLite以及其他簡單的數據庫。 – 2011-03-10 19:21:56

+1

@tc - 是的。即使SQLLite也可以。即使訪問。我還沒有運行一個沒有的數據庫。 – Thomas 2011-03-10 19:22:41

+3

爲什麼這會降低投票率? – 2011-03-10 19:23:10

12

我曾與1000個查詢運行測試。 SELECT EXISTSSELECT COUNT快大約25%。將limit 1添加到SELECT COUNT沒有任何區別。

+15

將'limit 1'添加到'select count'不會有任何區別,因爲'select count'返回一行。 :-) – Ken 2011-03-10 19:27:35

1

我不知道這對於優化有多好,但它的功能應該和exists一樣。例外是如果沒有匹配,它將不返回任何行。

SELECT true from mytable where a = "foo" and b = "bar" LIMIT 1; 
+0

難道這不會返回多行,每行都有一個單一的值'true'? – 2011-03-10 19:32:28

+0

抱歉,我忘記了編輯中的「限制1」。感謝您指出了這一點! – 2011-03-10 19:33:31

2

最可靠的方法可能是LIMIT 1,但那不是重點。

假設你有一個像CREATE INDEX mytable_index_a_b ON mytable (a,b)這樣的索引,MySQL應該足夠聰明,可以從索引中返回計數並且根本不觸及任何行。 LIMIT 1的好處可能可以忽略不計。

如果你沒有(a,b)的索引,那麼性能將會很差。極限1可能會使它明顯不那麼可怕,但它仍然是可怕的。

+0

那麼,我已經繼承了一個遺留的代碼庫,並且性能*很糟糕。 :-) – Ken 2011-03-10 19:41:42

+0

@Ken:通過數據庫並添加大量索引可能是值得的 – 2011-03-12 04:37:06

+0

明顯的索引已經存在,其中一些是相當大的表,插入性能也很重要。 – Ken 2011-03-15 20:54:50

2

這也可能是一種方法。

select 1 from mytable where a = "foo" and b = "bar" limit 1; 

這不會導致滿足where條件的所有記錄,而是在第一次「命中」後返回'1'。 缺點是你需要檢查結果,因爲可能有空記錄集的回報。

相關問題