示例1.字段c.alias
是唯一的。索引字段+限制1與性能方面的獨特字段比較| MySQL
Select c.* from category c where c.alias = 'some-alias'
例2領域c.alias
被簡單地索引。
Select c.* from category c where c.alias = 'some-alias' limit 1
這兩個例子在查詢性能方面有所不同嗎?
示例1.字段c.alias
是唯一的。索引字段+限制1與性能方面的獨特字段比較| MySQL
Select c.* from category c where c.alias = 'some-alias'
例2領域c.alias
被簡單地索引。
Select c.* from category c where c.alias = 'some-alias' limit 1
這兩個例子在查詢性能方面有所不同嗎?
你的問題的答案是測試和找出答案。
但是,如果有區別,我認爲它會非常小。在這兩種情況下,where
子句都應該使用索引。你真的在問MySQL是否「知道」在第一場比賽後停止(因爲唯一索引)。或者MySQL需要查看下一個值,看看它是不同的。這第二步將會有很小的開銷。
我也會提供,如果這是一個關於優化代碼的嚴重問題,那麼你可能看錯了地方。這種微觀優化(在這種情況下可能是納米)通常不會有幫助。
我應該注意到,如果您將主鍵索引與常規索引進行比較,您可能會看到可測量的差異。在MySQL中,主鍵會自動聚集,這可能是一個(小但可度量的)性能差異。
(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
的常見誤解。
謝謝,裏克! – Alliswell
好的。主鍵與唯一鍵相比有相同的可測量差異嗎? – Alliswell
謝謝,戈登! – Alliswell