我有一個包含80百萬條記錄的表。該表的結構:使用LIKE進行搜索的大型MySQL表的分區
- ID - 自動增量,
- 代碼 - 從5到100個字符的字母數字代碼,
- 等領域。
最常用的查詢是
SELECT * FROM table
WHERE code LIKE '%{user-defined-value}%'
查詢的數量越來越多,以及在recodrs計數。很快我會遇到性能問題。
有什麼辦法可以拆分零件中的表格嗎?或者也許還有其他方法來優化表格?
我有一個包含80百萬條記錄的表。該表的結構:使用LIKE進行搜索的大型MySQL表的分區
最常用的查詢是
SELECT * FROM table
WHERE code LIKE '%{user-defined-value}%'
查詢的數量越來越多,以及在recodrs計數。很快我會遇到性能問題。
有什麼辦法可以拆分零件中的表格嗎?或者也許還有其他方法來優化表格?
在搜索領先的%
是這裏的殺手。它否定了任何索引的使用。
我能想到的唯一事情就是根據代碼長度對錶進行分區。
例如,如果輸入的代碼長度爲10個字符,則首先使用10個字符代碼搜索表格,而不使用前導百分號,然後使用11個字符代碼搜索帶有前導百分號的表格,以及然後是帶有12個字符代碼的表格,帶有百分號,等等。
這使您無需搜索長度小於10個字符且永遠不會匹配的所有代碼。此外,您可以使用索引進行其中一項搜索(第一項)。
這也有助於保持表格尺寸略小。
儘管您可能想動態創建查詢,但您可以使用UNION
一次執行所有查詢。
您還應該看看FULLTEXT索引可能是更好的解決方案。
的幾點思考:
您可以將表格分成基於一定條件的多個較小的表。例如,在ID
可能或可能是code
或可能是任何其他字段。這基本上意味着你保持某種類型的表中的記錄和分離不同類型分成不同的表
如果可能的話。清除舊條目,或者您可能至少把它們移動到另一個存檔表
代替LIKE的,可以考慮使用REGEXP的正則表達式搜索
而不是運行SELECT *
,試着只選取選擇性列SELECT id, code, ...
我不確定此查詢是否與您的應用程序中的某個搜索有些相關,其中用戶輸入的值與code
列進行比較,並將結果回顯給用戶。但是,如果是的話,您可以嘗試在搜索查詢中添加選項,例如詢問用戶是否想要完全匹配或者應該從匹配開始。這種方式您不一定每次都需要運行LIKE匹配
This應該是第一點,但我認爲你在表格上有正確的索引
嘗試使用更多的查詢緩存。使用它的最好方法是避免頻繁更新表,因爲每次更新都會清除查詢緩存。所以更少的更新,更可能是MySQL緩存查詢,這將意味着更快的結果
希望以上幫助!
一些好點。爲了澄清,REGEXP在性能方面不會比LIKE好(可能更糟糕)。查詢緩存僅用於搜索相同的地方。 – Ami 2012-03-25 12:26:54
其實,我已經添加了另一列「code_inverted」來解決領先的「%」問題。 我會嘗試按照您的建議按代碼長度拆分表格。 – Leksat 2012-03-25 12:07:34
不錯。請注意,code_inverted只有在沒有結尾%(即成爲新的前導%)時纔會解決帶有前導%的問題。 :) – Ami 2012-03-25 12:20:48