【问题标题】:Hanging Query when joining multiple tables and counting rows连接多个表并计算行数时挂起查询
【发布时间】:2017-01-06 15:08:52
【问题描述】:

我正在尝试编写一个查询,该查询将生成一个商家列表,然后计算他们拥有多少库存商品以及每个商家有多少订单。 Merchants、Inventory Items 和 Orders 都在不同的表格中。我希望返回看起来像这样:

Site    | Inventory Items | Orders
London  | 7282            | 1234996
Glasgow | 9829            | 734949

我可以通过这个查询几乎立即获得站点和库存计数列表:

SELECT M.name AS 'Site',
       COUNT(II.idInventoryItems) AS 'Inventory Items',
FROM Merchants M
JOIN
  (SELECT idMerchants,
          idInventoryItems
   FROM InventoryItems) AS II ON II.idMerchants = M.idMerchants
GROUP BY M.name

我可以通过非常相似的查询获得站点和订单列表。但是当我将两者结合起来时,查询会无限期挂起,我必须取消查询。这是我一直在使用的完整查询:

SELECT M.name AS 'Site',
       COUNT(II.idInventoryItems) AS 'Inventory Items',
       COUNT(O.idOrders) AS 'Orders'
FROM Merchants M
JOIN
  (SELECT idMerchants,
          idInventoryItems
   FROM InventoryItems) AS II ON II.idMerchants = M.idMerchants
JOIN
  (SELECT idMerchants,
          idOrders
   FROM Orders) AS O ON O.idMerchants = M.idMerchants
GROUP BY M.name

通过相当快的查询可以实现我想要做的事情吗?如果是这样,我做错了什么?

【问题讨论】:

  • 你检查索引了吗?
  • 另外,你真的需要使用子查询吗?你不能简单地加入 Orders 和 InventoryItems 吗?据我所知,MySQL 并没有真正针对子查询进行优化
  • @Sebastianb 由于MIIMO 之间的1:M 关系,这里需要子查询。在OrdersInventoryItems 之间发生的多对多会人为地增加计数,从而提供不正确的计数;因此子查询需要首先获得计数然后加入。这就是为什么我相信克里斯的回答会奏效。

标签: mysql join count freeze


【解决方案1】:

试试这个。将计数移动到派生表将为您提供连接所需的数据,并允许 mysql 在出于性能目的需要时使用 idMerchants 上的索引进行优化。然后,您将连接两个行数明显减少的派生表,这也将提高性能。

SELECT M.name AS 'Site',
   II.count AS 'Inventory Items',
   O.count as 'Orders'
FROM Merchants M
JOIN
  (SELECT idMerchants, COUNT(idInventoryItems) AS 'count'
   FROM InventoryItems GROUP BY idMerchants) AS II ON II.idMerchants = M.idMerchants
JOIN
  (SELECT idMerchants,
      COUNT(idOrders) AS 'count'
   FROM Orders GROUP BY idMerchants) AS O ON O.idMerchants = M.idMerchants

【讨论】:

  • 克里斯,我同意这可行,但除了 SQL 之外,解释你的答案将是有益的。
  • 不错的更新。为什么与如何一样,有时甚至更重要。请注意,如果他们不这样做,计数将不正确地被 II 和 O 之间的 M:M 夸大。如果使用不同的计数可能能够解决,但他们不会从性能中受益得到你的提及。
  • 我按 M.name 离开了群组,但不确定 OP 是否还需要它??可能需要删除,因为不再在该级别进行聚合。
  • 答案已编辑以删除多余的“按名称分组”
  • 太棒了!它工作得非常快,正是我想要的。我在挂起其他查询时遇到了类似的问题,所以我将看看我是否可以使用这个答案中的解释来修复我的其他问题。非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多