MySQL性能:按联接表的内容排序

时间:2018-05-09 01:56:22

标签: mysql performance join indexing denormalization

有没有办法在根据较大表的动态子集排序查询时提高性能?

作为参考,我有两张桌子:

  • 产品 - 包含有关产品的详细信息,包括名称,价格等。
  • 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)进行连接,我不认为我可以添加到该表中的有用索引通过该表中的不同列(例如产品名称)进行排序时提高性能。单品"有很多"库存商品,因此我无法将inventory_id添加到产品表中。

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

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

2 个答案:

答案 0 :(得分:0)

ant update

答案 1 :(得分:0)

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

  

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

     

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

索引可用于排序,如果确实如此,则排序性能将得到改善。

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