2014-09-21 75 views
0

我會試着解釋我的情況:我試圖爲我的網站上的產品創建一個搜索引擎,所以當用戶需要找到一個產品時,我需要顯示類似的產品,這裏是一個例子。MySQL的全文搜索匹配類似的結果

用戶搜索:
assassins creedassassinscreedaSsAssIn's CreeD假設沒有字母/數字拼寫錯誤(這3個查詢應產生相同的結果)

預期結果:
Assassin's CreedAssassin's Creed: UnityAssassin's Creed: Special Edition

我到目前爲止試過了什麼

  • 我已經創建了一個MySQL字段包含了產品的解析名稱的搜索引擎(Assassin's Creed: Unity -> assassinscreedunity
  • 我分析
  • 我搜索使用MySQL的INSTR()

我的問題

搜索查詢

我很好,通過使用這個,但我聽到它可以慢,當行數增加,我創建了一個全文索引在我的表中,但我不認爲這會有所幫助,所以我需要另一個溶膠ution。
感謝您的任何回答,並在downvoting之前問我任何問題。

+1

您是否遇到性能問題或者您是否聽說過它可能會很慢? – andy 2014-09-21 10:12:24

+0

@andy我在某處讀過,它和'LIKE'一樣,它不經過使用和索引而遍歷所有記錄,所以我認爲當行數增加時它會減慢很多。 – 2014-09-21 10:13:56

+0

您期待的行數是多少?如果您只有一個包含幾百個遊戲名稱的表格,則無需擔心。 – andy 2014-09-21 10:18:21

回答

0

首先,您應該更清楚地瞭解您的查詢中的性能問題,而不是「聽起來很慢」和「認爲它會有所幫助」。一個起點可能是Slow Query Log

如果您有一個表在多行中包含相同的分析名稱,請考慮normalizing您的數據庫。在特定情況下,將唯一解析的名稱存儲在一個表中,並且只在您的問題中描述的表中對應的解析名稱的ID。這樣,您只需要檢查具有唯一名稱的小表,然後可以通過ID快速查找主表中的所有匹配條目。

例子:

下表考慮與結構

id | product_name  | rating 
----------------------------------- 
1 | assassinscreedunity | 5 
2 | assassinscreedunity | 2 
3 | monkeyisland  | 3 
4 | monkeyisland  | 5 
5 | assassinscreedunity | 4 
6 | monkeyisland  | 4 

你就必須掃描所有六個條目中找到相關的行。

相比之下,考慮兩個表是這樣的:

id | p_id | rating 
-------------------- 
1 | 1 | 5 
2 | 1 | 2 
3 | 2 | 3 
4 | 2 | 5 
5 | 1 | 4 
6 | 2 | 4 

id | name 
-------------------------- 
1 | assassinscreedunity 
2 | monkeyisland 

在這種情況下,你只需要掃描兩個條目(比六),然後可以高效地查找使用整數ID相關行。

爲了進一步提高性能,可以擴展解析名稱的概念並使用散列。例如,您可以計算解析名稱的SHA1哈希值,該哈希值是一個160位的值。您可以非常有效地在數據庫中找到此值的條目。要匹配子字符串,也可以將它們添加到第二個表中。由於散列只需要計算一次,您仍然可以使用數據庫通過整數進行匹配。另一件事你可能是fuzzy hashing

另外,您應該詳細閱讀Rabin–Karp algorithmstring searching

+0

這不是一個查詢速度的問題,這是一個問題「什麼函數/方法可以用來獲得更快的結果(比使用'INSTR()')時我有類似10000+行的東西,爲了不一一解析它們?「。具有相同的解析名稱並不是問題,因爲它會在整個表中出現3/4次,所以不值得創建單獨的表格 – 2014-09-22 13:49:27

+0

@RomanHudylko將相同的解析名稱縮減爲單個實例可減少要搜索的行數3-4倍!對於功能部分,我更新了答案。 – andy 2014-09-22 13:56:40

+0

爲相同名稱創建單個實例沒有任何意義,因爲具有相同名稱的行具有不同的ID ...至於更新:我不認爲我完全理解它應該如何幫助我。我需要能夠找到類似的值,這就是爲什麼我使用INSTR(),我該如何使用SHA1-Hash,你能給我一個例子嗎? – 2014-09-22 14:02:55