2016-12-29 60 views

回答

1

你的問題的答案是測試和找出答案。

但是,如果有區別,我認爲它會非常小。在這兩種情況下,where子句都應該使用索引。你真的在問MySQL是否「知道」在第一場比賽後停止(因爲唯一索引)。或者MySQL需要查看下一個值,看看它是不同的。這第二步將會有很小的開銷。

我也會提供,如果這是一個關於優化代碼的嚴重問題,那麼你可能看錯了地方。這種微觀優化(在這種情況下可能是納米)通常不會有幫助。

我應該注意到,如果您將主鍵索引與常規索引進行比較,您可能會看到可測量的差異。在MySQL中,主鍵會自動聚集,這可能是一個(小但可度量的)性能差異。

+0

好的。主鍵與唯一鍵相比有相同的可測量差異嗎? – Alliswell

+0

謝謝,戈登! – Alliswell

1

(Gordon的回答是不錯,但我有一些不同的東西說...。)

SELECT ... WHERE unique_col = constant - 這將從表中讀取一行(如果有的話)。除了平凡的解析時間之外,LIMIT 1沒有任何影響。

SELECT ... WHERE non_uniq_col = constant - 這將讀取,直到找到一個不匹配的行。也就是說,它將讀取N + 1行以傳送N行。對於這種情況,LIMIT 1會阻止它縮短。現在問題不在於性能(如果N很小,沒有太大區別),而是關於功能(是否需要1行或N)。

在InnoDB中,PRIMARY KEY與數據「聚集在一起」,並且隱含地爲UNIQUE。所以如上所述。

中學鍵,還有一個額外的步驟。首先在索引BTree中找到(col=const)行。在BTree的葉節點是所需行的PK。額外的步驟是深入PK的BTree找到該行。這需要花費一些額外的費用,但對於中小型的桌子來說,這是很少值得擔心的。 (該LIMIT 1問題仍然適用,是次要的。)

如果所有SELECT引用的列在同一個二級指標(包括PK的隱式副本),那麼該指數被認爲是「覆蓋」。因此,查詢可以完全在二級索引的BTree中執行,從而避免了額外的步驟。再次,這通常很小,但可能值得做。 「覆蓋」在EXPLAIN中用「使用索引」(而不是「使用索引條件」,它指的是不同的東西)表示。

我可以建議你學習我的Indexing Cookbook,而不是先了解血淋淋的細節。我的文檔爲您提供了關於性能的重要內容,並省略了一些不太重要的細節,例如這個問題正在討論什麼。

對於微小在小批量項目中的表格,這些都不重要。
對於巨大的表,磁盤命中數是主要的性能指標;最小化這成爲目標。特別是,二級索引的額外步驟通常涉及N個磁盤命中(對於N行)。

但是... SELECT ... GROUP BY ... ORDER BY ... LIMIT 1可能涉及獲取一堆行,排序它們,最後交付1行。 如果排序不能在索引中消耗,則可能會多次處理N行。在這個的情況下,LIMIT 1僅在花費了99%的努力之後才起作用。對於新手來說,這是一個關於LIMIT的常見誤解。

+0

謝謝,裏克! – Alliswell