【问题标题】:Sorting items filtered by tag对按标签过滤的项目进行排序
【发布时间】: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


【解决方案1】:

有一个标准的替代方案 - 更改服务器系统变量。 例如,您可以试验 sort_buffer_size 值(默认 2MB)。 More 关于它。

【讨论】:

  • 问题不仅在于文件排序,还在于创建临时表。大多数时间它都花在复制到临时表上。我可以用它做些什么吗?
  • 对不起,没有。这是 MySQL 的限制。
【解决方案2】:

一旦您使用 JOIN 并在连接表中过滤掉,您就会陷入糟糕的性能。

正如你所说,避免这种情况的唯一方法是创建一个非规范化表。

对于 SO 的排序,我认为他们没有这样的问题:他们只需按答案表的一列对答案进行排序(类似于 SELECT * FROM answers WHERE question_id = 1234 SORT BY answer_date,索引在 question_id, answer_date)

我也在寻找这样的解决方案,多值列,这真的很难(非规范化数据会很大,因为它需要跨越多值列中的所有值)

【讨论】:

  • 所以有这样的问题:当你按标签过滤时,你会首先看到最新的问题(或者最热门的,没关系)。
猜你喜欢
  • 2013-05-25
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-08
  • 2018-02-19
  • 2012-03-10
相关资源
最近更新 更多