【发布时间】:2011-05-16 20:11:20
【问题描述】:
我想实现一个非常常见的功能——按标签过滤一些项目。互联网上有很多教程,其中包含如何操作的示例。查询非常简单快速(假设存在适当的索引)。
但通常过滤后的项目需要按某个字段进行排序。例如,当您在 SO 上按标签过滤问题时,您的结果会被排序。
要完成这项任务(假设我们需要按评分排序),可以这样写:
SELECT item.id FROM item
INNER JOIN taggeditem ON taggeditem.item_id = item.id
WHERE
taggeditem.tag_id = 1234
ORDER BY item.rating DESC
我们有索引(taggeditem.tag_id)、(item.id)、(item.rating)
这个查询的问题是 mysql 不能在 item.rating 上使用索引,因为用于获取行的键与 ORDER BY (MySQL: ORDER BY Optimization) 中使用的键不同。这会导致使用临时表和文件排序,进而导致执行时间变慢。
我想出的解决方案是将排序字段非规范化为taggeditem 表,以便我可以在taggeditem 上创建索引(tag_id, item_rating)。
我在 SO 搜索过类似的问题,只找到了这个:Mysql slow query: INNER JOIN + ORDER BY causes filesort。解决方法是一样的。
所以,我想问一下,这是解决这个问题的常用方法吗?将一堆排序字段非规范化为 taggeditem(例如 created、rating)是一种好习惯吗?在 SO,您可以使用 4 个不同的参数(最新、热门、投票、活动)进行排序——这是否意味着它们对用于排序结果的字段进行了非规范化? 此解决方案有其他替代方案吗?
【问题讨论】:
-
是物品还是物品?混淆...您可能需要重新检查 SQL
-
我编辑了SQL,当然是表项
标签: mysql join tags query-optimization sql-order-by