作为这个问题的更一般情况,因为我认为它可能会引起更多人的兴趣...在两个表上执行全文搜索的最佳方法是什么?假设有三个表,一个用于程序(带有submitter_id),另一个用于带有object_id的标签和描述:外键引用程序中的记录.我们希望程序的submitter_id在其标签或描述中包含某些文本.我们必须使用MATCH AGAINST,因为我不会在这里讨论.不要挂在这方面.
programs id submitter_id tags_programs object_id text descriptions_programs object_id text
以下工作并在20ms左右执行:
SELECT p.submitter_id FROM programs p WHERE p.id IN (SELECT t.object_id FROM titles_programs t WHERE MATCH (t.text) AGAINST ('china') UNION ALL SELECT d.object_id FROM descriptions_programs d WHERE MATCH (d.text) AGAINST ('china'))
但我尝试将此作为JOIN重写如下,并且它运行了很长时间.我必须在60秒后杀死它.
SELECT p.id FROM descriptions_programs d, tags_programs t, programs p WHERE (d.object_id=p.id AND MATCH (d.text) AGAINST ('china')) OR (t.object_id=p.id AND MATCH (t.text) AGAINST ('china'))
出于好奇,我用AND取代了OR.这也在几毫秒内运行,但这不是我需要的.上面的第二个查询出了什么问题?我可以和UNION和子选择一起生活,但我想了解.
过滤后加入(例如加入结果),不要尝试加入然后过滤.
原因是您丢失了全文索引的使用.
澄清回应评论:我在这里使用了一般性的词,而不是作为JOIN
合并或组合的同义词.
我基本上说你应该使用第一个(更快的)查询,或类似的东西.它更快的原因是每个子查询都足够整洁,db可以使用该表的全文索引来非常快速地进行选择.加入两个(可能小得多)的结果集(with UNION
)也很快.这意味着整个过程很快.
慢速版本通过大量数据进行测试,以查看它是否符合您的要求,而不是快速将数据下调,只搜索您可能真正想要的行.