2013-06-01 24 views
0

我有一個MySQL表,我希望我的主鍵是一個字符串。該字符串可能會更長(數百個字符)。MySQL - 主鍵字符串比較的速度

一個非常常見的查詢將是INSERT ... ON DUPLICATE KEY UPDATE,這意味着MySQL將不得不檢查主鍵是否已經在表中存在很多。如果這是用一個天真的strcmp完成的,我想這可能需要相當長的一段時間,字符串。因此,手動對字符串進行散列(對較短的字符串或其他數據類型)並將其用作我的主鍵或者我可以直接使用長字符串會更好嗎? MySQL是否在內部散列主鍵字符串?

+1

你不會以一己之力智取一個代碼庫,擁有數百萬線和數百觀察員。讓MySQL做它的事情。 –

+2

在這裏閱讀http://stackoverflow.com/questions/517579/strings-as-primary-keys-in-sql-database – Yogus

回答

3

首先,當你在varchar字段上有索引時,mysql不會在所有條目上執行strcmp以查找正確的;而是使用binary tree,這比strcmp要快很多,以便找到正確的條目。

注意:如果需要,我會提供一些提高性能的信息,但請不要這樣做,直到您遇到實際問題。 Varchar索引很快,它們已經被很多非常聰明的人所優化,並且在絕大多數情況下,它會超出您的需要。這就是說,如果你有很多條目和/或非常長的鍵,那麼在它上面使用散列索引可能是一個不錯的性能。

CREATE TABLE users 
(
    username varchar not null, 
    username_hashed varchar(32) not null, 
    primary key (username), 
    index (username_hashed) 
); 

例如,當您插入時,您可以設置username_hashed = md5(username)。然後你用類似select otherfields from users where username_hashed = md5(username) and username = username

這樣的東西搜索請注意,它似乎mysql 5.5 support hash index natively,這將允許你不必手動做。

+0

我爲你的答案的第一部分+1,但你的'username_hashed = md5(用戶名)'建議是一個可怕的。除了重複條目的可能性之外,添加列僅僅會減慢速度,因爲需要(a)計算和存儲它以及(b)維護索引。 –

+0

@Denis:重複實際上並不是一個問題,因爲你檢查哈希值,然後檢查實際值(所以即使你有碰撞 - 我同意你最終會這樣做),那麼mysql必須只匹配幾個條目而不是整個指數)。而且我發現,儘管插入速度有所減慢(主鍵上沒有更新),但它在達到數百萬條長字符串後,在選擇速度方面提供了非常好的提升。取決於你的需求我猜,因此我大膽的警告,如果可能的話,我會用一個更清晰的設計,但如果不這樣做可以幫助。 – Lepidosteus

+0

「重複實際上並不是一個問題,因爲您檢查散列,然後是實際值」 - 但是,主鍵的索引將始終得到使用,散列值根本不會被使用 - 除非緩慢通過添加一個單獨的檢查查詢下來。還是MySQL實際上試圖在散列值上使用索引? –