2010-02-21 79 views
2

這將是其中一個問題,但我需要問一下。MySQL:SELECT(x)WHERE vs COUNT WHERE?

我有一張大桌可能有或沒有一個獨特的行。因此,我需要一個MySQL查詢,它會告訴我TRUE或FALSE。

用我的當前的知識,我看到兩個選項(僞碼):

[ID =主鍵]

OPTION 1:

SELECT id FROM table WHERE x=1 LIMIT 1 
... and then determine in PHP whether a result was returned. 

選項2:

SELECT COUNT(id) FROM table WHERE x=1 
... and then just use the count. 

無論是出於任何原因,這些都是可取的,還是有可能是更好的解決方案?

謝謝。

回答

3

如果選擇標準是真正唯一的(即最多得到一個結果),那麼通過在該標準中包含一列(或多列)的索引,您將看到大規模的性能改進。

create index my_unique_index on table(x) 

如果要強制唯一性,甚至不是一種選擇,你必須有

create unique index my_unique_index on table(x) 

有了這個索引,查詢的唯一標準,將執行得非常好,無論未成年SQL的調整像count(*),count(id),count(x),limit 1等等。 爲清楚起見,我會寫

select count(*) from table where x = ? 

我會避免LIMIT 1其他兩個原因:

  • 這是非標準SQL。我對此沒有信心,在必要時使用MySQL特有的東西(即用於分頁數據),但這裏沒有必要。
  • 如果由於某種原因,您有多行數據,這可能是您應用程序中的一個嚴重錯誤。有了LIMIT 1,你永遠不會看到問題。這就像計算侏羅紀公園中的恐龍數量,假設這個數字只有可能下降。
+0

對於侏羅紀公園的類比。我可能會偷走它。對於其餘論點的贊成 - 我完全同意。 – 2010-02-21 07:30:17

+0

感謝您的回答,儘管我喜歡使用LIMIT 1.非標準SQL不會打擾我(只要它有效),而對於第二個參數,在我的應用程序中看到這樣的錯誤幾乎與恐龍復活。 :) – Tom 2010-02-21 15:27:06

1

AFAIK,如果您的ID列上有索引,那麼這兩個查詢的性能會差不多。第二個查詢在你的程序中需要少一行代碼,但這也不會對性能產生影響。

+0

ID列上的索引在這裏沒什麼大不了,OP想要X上的索引。 – Thilo 2010-02-21 06:15:24

+0

噢,對不起,這是X – e4c5 2010-02-21 08:09:43

0

通常,您使用group by having子句來確定表中是否存在重複行。如果你有一個帶有id和名字的表格。 (假設id是主鍵,並且您想知道名稱是唯一的還是重複的)。您可以使用

select name, count(*) as total from mytable group by name having total > 1; 

以上將返回重複名稱的數量和次數。

如果您只想讓一個查詢將您的答案設爲true或false,則可以使用嵌套查詢,例如,

select if(count(*) >= 1, True, False) from (select name, count(*) as total from mytable group by name having total > 1) a; 

上面應該返回true,如果你的表有重複行,否則爲false。

+1

因爲他正在做極限1,我懷疑OP是在尋找重複。 – Thilo 2010-02-21 06:35:46

1

就我個人而言,我通常會做第一次從行中選擇id並限制爲1行。我從編碼的角度來看更好。不必實際檢索數據,我只需檢查返回的行數。

如果我要比較速度,我會說在MySQL中不做計數會更快。我沒有任何證據,但我的猜測是,MySQL必須獲得所有行,然後統計有多少行。 Altough ...在第二個想法中,它也必須在第一個選項中這樣做,所以代碼也會知道有多少行。但既然你有COUNT(id)COUNT(*),我會說它might be slightly slower

1

直觀上,第一個可能會更快,因爲它可以在找到第一個值時中止表(或索引)掃描。但是您應該檢索x not id,因爲如果引擎使用x上的索引,則不需要轉到實際所在行的塊。

另一種選擇可能是:

select exists(select 1 from mytable where x = ?) from dual 

這已經返回一個布爾值。