2013-10-25 33 views
0

我僱用了一位db顧問,他一直推薦使用solr來處理我當前完全mysql系統的全文搜索,以加快通常很慢的搜索(每次搜索最多30秒)。什麼是這個系統更好的solr查詢?

他/我們的大部分已經花了a)調整mysql設置來擠出額外的性能,b)安裝solr。然而,現在我們已經接近我們這個時代的末期,而且前幾個solr測試查詢似乎正在倒下。

首先,這裏是我當前完整的Mysql設置的相關3個表格,以及我們試圖用MySQL/Solr方法替換的完全MySQL查詢。然後是我們正在測試的Solr查詢。

TABLE1 - 全文搜索記錄存儲在其中的主表。它們包括一個songID列,Artist列和Title列。 INDEXES - songID小學,藝術家全文(非唯一),藝術家btree(非唯一),標題全文(非唯一),標題btree(非唯一)

TABLE2 - 用於存儲DJ歌曲列表。它引用上表的ID。一些DJ擁有150,000多首歌曲,因此在這裏有超過150,000多行用於引用TABLE1中的歌曲。 TABLE2還有一個ID列,加上歌曲版本列(命名版本),因此DJ可以將自己的版本引用應用於同一首歌曲的多個版本(即同一首歌曲有多行,每行版本數據不同)。 INDEXES - ID主鍵,djID btree(非唯一),songID btree(非唯一)。

TABLE3 - 一個標籤映射表,包含對TABLE2中ID的引用,以及標籤的ID(在另一個名爲TAGS的表中)。它將TABLE2中每首歌曲的標籤存儲爲流派,語言,十年,再加上DJ可以有多個歌曲列表(標記爲List1,List2等),因此每首歌曲都包含歌曲列表。潛在地,每首歌曲最多可以有12個標籤。 INDEXES - rowID primary,ID btree(非唯一),tag_id(非唯一)

以下是關於藝術家關鍵字「beatles」的當前mysql搜索查詢,唯一涉及的標記是告訴我們只選擇歌曲匹配在DJ 33的清單1中:

"SELECT t1.*, t2.version 
FROM table1 t1, table2 t2, tagmap tm, tag t 
WHERE MATCH (t1.Artist) AGAINST ('+beatles* ' IN BOOLEAN MODE) 
AND tm.tag_id = t.tag_id 
AND (t.name IN ('List1')) 
AND t2.ID = tm.ID 
AND t2.songID = t1.songID 
AND t2.djID = '33' 
GROUP BY t2.ID 
HAVING COUNT(tm.tag_id)=1 
ORDER BY t1.Artist, t1.Title ASC LIMIT {$lastRowNum},{$limit1}";// pagination blah 

它可以工作,但在列表大於5000時,速度很慢。

他提出的SOLR SOLUTION:

  • 用於在搜索過程中TABLE1
  • 的歌曲使Solr的索引,在MySQL屬於DJ問題
  • 創建songIDs查詢TABLE2在藝術家關鍵字solr查詢,並注入DJ的歌曲ID到它...

    .../solr/select /?q = id:(3688804 3688807)AND藝術家:披頭士&重量= JSON

(我離開了網址了,而且空間和支架,因此很容易查看這裏,但它們是由%20等的工作代碼替換)

這上面只有2首歌曲ID的例子似乎可行,但在測試中,只要您開始向其添加大約1000多首歌曲ID,查詢就會失敗。考慮到一些DJ有150,000多首歌曲,因此可能有150,000多個獨特的歌曲ID注入到solr查詢中,這似乎是一個有缺陷的解決方案。

此外,我不知道標籤將如何進入查詢過程。

感謝您的關注。

回答

1

我會建議你使用Solr,但是在一個稍微不同的實現中。

你所有的DB正常化的偉大工程交易系統(即添加歌曲,播放列表創建等)

搜索的東西,效果最好的一個反規範化的數據結構。您可以創建一個Solr Schema來表示您的搜索結果並使用SQL查詢填充它。

該查詢仍然無效,但不需要在每個搜索(即實時)上運行。相反,每當歌曲/播放列表等發生變化時,您可以每晚對索引進行批量填充並緩慢增量更改。

我在這個here上寫了一些東西。希望這可以幫助。

+0

感謝Srikanth--我在本週末測試了一個非規範化系統。 – Shaun