在最短的时间内通过多个标签搜索对象

时间:2013-11-28 12:18:41

标签: php mysql search taxonomy tagging

我想按标签搜索对象。我想出的第一种方法是以下模型:

Object(OID, Tags, ...)
Tag(TagID, Name, ...)
ObjectTag(OID, TagId)

字段Tags包含所有标记名称。

现在,我不仅希望通过一个标签搜索,而是通过许多标签搜索。查询看起来像这样:

SELECT `o`.*
FROM Object o
  INNER JOIN ObjectTag tag1 ON(o.OID = tag1.OID)
  INNER JOIN ObjectTag tag2 ON(o.OID = tag2.OID)
  ...
  INNER JOIN ObjectTag tagn ON(o.OID = tagn.OID)
WHERE tag1.TagID = ?  AND tag2.TagID = ? AND ... AND tagn.TagID = ?

我用大约100k个对象和每个对象5-20个标签测试了它,它花了大约30秒或更长时间,因此它经常超过PHP时间限制。

出于好奇,我还尝试使用LIKE基于字段标记进行查询。

SELECT `o`.*
FROM object
WHERE object.tags LIKE '%tag1%' AND object.tags LIKE = '%tag2%' ...

但是,此查询在10秒内执行。不知怎的,我可以理解扫描一个表比交叉操作更快,但这样我就不能使用索引了。

我的目标是响应时间,不会吓跑用户。

1 个答案:

答案 0 :(得分:1)

我假设您的索引针对第一个示例进行了优化。

而不是您的第一个查询具有所有这些连接,您是否尝试加入一次,然后确保每个记录都有该标记。请注意,HAVING子句的N值取决于您要搜索的标记数。

SELECT object.keyfield, COUNT(*)
FROM object
JOIN objectTag
  ON object.OID = objectTag.OID
WHERE objectTag.TagID IN (tag1,tag2,tag3...tagN)
GROUP BY object.keyfield
HAVING COUNT(*) >= N

您未提供具有预期结果集的任何样本数据。你也没有明确地显示SELECT子句,所以这是最好的猜测。

相关问题