我想实现一个非常常见的特性——通过标签过滤一些项目。因特网上有许多教程,其中有一些如何做的例子。查询非常简单和快速(假设存在适当的索引)。
但通常筛选的项目需要按某个字段排序。例如,当您按标签筛选问题时,您将对结果进行排序。
要完成这项任务(假设我们需要按评级排序),可以写下:
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使用index,因为用于提取行的键与ORDER BY中使用的键不同。(
MySQL: ORDER BY Optimization
)这会导致使用临时表和文件排序,从而导致执行时间变慢。
我提出的解决方案是将排序字段非规范化为
taggeditem
表,以便创建索引
(tag_id, item_rating)
在
条目项目
.
我在SO上搜索过类似的问题,只找到了一个:
Mysql slow query: INNER JOIN + ORDER BY causes filesort
. 解决办法是一样的。
所以,我想问,这是解决这个问题的一个常见方法吗?将一组排序字段非规范化为标记项(如已创建、分级)是一个好的实践吗?因此,您可以使用4个不同的参数(最新的、热门的、投票的、活跃的)进行排序——这是否意味着它们是用于排序结果的非规范化字段?
这个解决方案还有其他选择吗?