我已经聘请了一名数据库顾问,他一直建议使用solr来处理我当前的完整mysql系统的全文搜索方面,以便加快搜索速度通常很慢(每次搜索最多30秒)
他/我们的大部分时间用于调整mysql设置以挤出额外的性能,以及b)安装solr。然而,现在我们已接近结束时间,并且前几个solr测试查询似乎正在倒下。
首先,这是我当前完全Mysql设置的相关3个表,以及我们试图用MySQL / Solr方法替换的完全MySQL查询。然后是我们正在测试的Solr查询。
TABLE1 - 存储全文搜索记录的主表。它们包含songID列,Artist列和Title列。 INDEXES - songID primary,Artist Fulltext(非独特),Artist btree(非独特),Title Fulltext(非独特),Title btree(非独特)
TABLE2 - 用于存储DJ歌曲列表。它引用了上表的ID。有些DJ有150,000多首歌曲,因此这里有150,000多行参考TABLE1中的歌曲。 TABLE2还具有ID列和歌曲版本列(命名版本),因此DJ可以将他们自己的版本引用应用于同一首歌曲的多个版本(即同一首歌曲的多行,每个版本具有不同的版本数据)。 INDEXES - ID primary,djID btree(非唯一),songID btree(非唯一)。
TABLE3 - 标记映射表,包含对TABLE2中ID的引用,以及标记的ID(在另一个名为TAGS的表中)。它为TABLE2中的每首歌曲存储标签,用于流派,语言,十年,加上DJ可以有多个歌曲列表(标记为List1,List2等),因此对每首歌曲所属的歌曲列表的引用。潜在地,每首歌曲每个DJ最多可以有12个标签。 INDEXES - rowID primary,ID btree(非唯一),tag_id(非唯一)
这是艺术家关键字“beatles”的当前mysql搜索查询,唯一涉及的标签是告诉我们只选择DJ 33的List1中的歌曲匹配:
"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解决方案:
在Artist上创建关键字的solr查询,并将DJ的songID注入其中......
... / solr / select /?q = id:(3688804 3688807)AND Artist:beatles& wt = json
(我离开了网址,还有空格和括号,因此在这里很容易查看,但在工作代码中它们被%20等替换)
上面只有2个歌曲ID的示例似乎有效,但在测试时,一旦您开始向其中添加大约1000多首歌曲ID,查询就会失败。考虑到一些DJ有150,000多首歌曲,因此有可能将150,000多个独特的songID注入到solr查询中,这似乎是一个有缺陷的解决方案。
另外,我不知道标签将如何进入查询过程。
谢谢你看看。
答案 0 :(得分:1)
我建议您使用Solr,但实现方式略有不同。
所有数据库规范化都适用于事务系统(即添加歌曲,创建播放列表等)
搜索是在非规范化数据结构上最有效的方法。您可以创建一个代表搜索结果的Solr Schema,并使用SQL查询填充它。
查询仍然无效,但不需要在每次搜索(即实时)上运行。相反,只要歌曲/播放列表等发生变化,您就可以每晚批量填充索引并进行涓流增量更改。
我在这个here上写了一些东西。希望这会有所帮助。