【问题标题】:MySQL Performance: Ordering by content of joined tablesMySQL 性能:按连接表的内容排序
【发布时间】:2018-10-19 01:05:59
【问题描述】:

在对基于较大表的动态子集的查询进行排序时,有没有办法提高性能?

作为参考,我有两张表:

  • 产品 - 包含有关产品的详细信息,包括名称、价格等。
  • inventory_items - 包含来自多个供应商的各种产品的当前库存水平。

一个常见的查询可能是这样的:

select (columns)
from inventory_items ii
left join products p on ii.product_id = p.id
where ii.vendor_id = 123
order by p.name
limit 100

因此,我们正在查看的 inventory_items 可能有 50k 行,这些行可能链接到 products 表中的 45k 行。 (在我们的例子中,左连接是必要的,因为我们并不总是拥有供应商库存中所有产品的产品数据。)

这相对较慢且难以建立索引:查询使用 products 表的主键 (id) 进行连接,而且我认为没有有用的索引可以添加到该表以提高排序时的性能通过该表中的不同列(例如产品名称)。一个产品“有很多”库存项目,所以我不能只在 products 表中添加一个inventory_id。

我目前正在考虑对表进行非规范化,方法是向inventory_items 表中添加我需要的列,或者为编译的报告创建一个新表。这样我就可以将索引添加到 inventory_items 表中,例如 (vendor_id, name) 这将有助于提高按名称排序时的性能。

这里有比非规范化更好的选择吗?缓存很困难,因为每个报告可以按十几个不同的字段进行排序,结果需要分页,并且用户可以对结果应用各种类型的过滤器/搜索。

【问题讨论】:

  • 唯一确定的方法是在创建索引之前和之后从查询中获取自己的解释计划。连接中使用的任何列的索引都会有所帮助,另外还有用于 where 子句中的列的索引。 p.name 上的索引可能会加快排序速度。见stackoverflow.com/questions/6858844/…

标签: mysql performance join indexing denormalization


【解决方案1】:
inventory_items needs INDEX(vendor_id)

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
【解决方案2】:

请参阅产品文档(例如)https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html#order-by-index-use

在某些情况下,MySQL 可以使用索引来满足 ORDER BY 子句并避免执行文件排序操作时涉及的额外排序。

即使 ORDER BY 与索引不完全匹配,也可以使用索引,只要索引的所有未使用部分和所有额外的 ORDER BY 列都是 WHERE 子句中的常量。

可以在排序中使用索引,如果是这样,那么排序性能将会提高。

因此,在您的示例中,p.name 上的索引可能会提高排序性能,但是,了解正在使用哪些索引以及何时使用它们的唯一方法是获取解释计划。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-18
    • 2012-07-16
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 1970-01-01
    相关资源
    最近更新 更多