2011-08-17 101 views
2

我正在構建一個論壇,並且正在尋找合適的方法來構建一個搜索功能,通過他們的姓名或職位名稱來查找用戶。我得到的是這樣的:MySQL:使用LIKE或FULLTEXT優化搜索

SELECT users.id, users.user_name, users.user_picture 
FROM users, subject1, subject2 
WHERE users.id = subject1.user_id 
AND users.id = subject2.user_id 
AND (users.user_name LIKE '%{$keywords}%' 
OR subject1.title1 LIKE '%{$keywords}%' 
OR subject2.title2 LIKE '%{$keywords}%') 
ORDER BY users.user_name ASC 
LIMIT 10 
OFFSET {$offset} 

LIMIT和OFFSET是分頁。我的問題是,當行數達到相當數量時,是否會通過多個表進行LIKE搜索,從而大大降低性能?

我有幾個備選方案: 一個,也許我可以重寫該查詢,使LIKE搜索在只返回索引user_ids的子查詢中完成。然後,我會根據該信息找到其餘的用戶信息。這會提高性能嗎?

第二,我想我可以在LIKE {$keyword}%的第一個通配符之前出現$keyword字符串。這樣,我可以索引user_name, title1, and title2列。但是,因爲我會在這裏交易速度的準確性,所以這會帶來多大的性能差異?爲索引這些列而犧牲這麼高的精度是否值得?

三,也許我可以給用戶3個搜索字段選擇,並且每個搜索只能通過一個表。這會提高性能嗎?

最後,我應該考慮使用FULLTEXT搜索而不是LIKE?兩者之間的性能差異是什麼?另外,我的表使用的是InnoDB存儲引擎,除非切換到MyISAM,否則我無法使用FULLTEXT索引。切換到MyISAM會有什麼重大區別嗎?

分頁是我擔心的另一個性能問題,因爲爲了執行分頁,我需要查找查詢返回的結果總數。目前,我基本上只是在做TWICE的查詢,因爲第一次使用時只用於COUNT的結果。

回答

3

,我們在您查詢兩件事情,以防止MySQL的使用指標,首先你的模式開始通配符%,MySQL不能使用索引來搜索與通配符啓動模式,其次,你在你的WHEREOR子句,您需要使用UNION來重寫您的查詢以避免使用OR,這也會阻止MySql使用索引。在不使用索引的情況下,MySql每次都需要執行全表掃描,並且所需的時間將隨着表中行數的增加而線性增加,是的,正如您所說的那樣「當行數會大大減慢性能時達到一個很大的數額「,所以我會說你唯一真正的可擴展選項是使用FULLTEXT搜索。

0

切換到MyISAM應該可以毫無用處地工作。唯一的缺點是,MyISAM會在插入/更新時鎖定整個表格,這可能會導致表格插入速度比選擇更慢。基本上,我認爲在不需要外鍵的情況下使用MyISAM,並且該表的選擇比插入選擇多得多,並且在表具有比選擇更多的插入/更新時使用InnoDB(例如,對於統計表) 。

在你的情況下,我猜想切換到MyISAM是更好的選擇,因爲全文索引功能更強大,速度更快。

它還提供了使用某些查詢修飾詞的可能性,如排除詞(「cat -dog」)或類似詞。但請記住,不可能像LIKE搜索一樣查找以短語結尾的單詞(「*bar」)。 「foo*」將工作。

+0

我期待有大量的寫入到我的表中,但不超過SELECT的數量。你會不會推薦我在這種情況下切換到MyISAM全文索引? – recount88 2011-08-17 13:25:33