【问题标题】:Optimizing SQL, Better Performance than JOIN优化SQL,性能比JOIN好
【发布时间】:2013-12-09 17:23:13
【问题描述】:

我有 3 个表,总共大约 20 万行。

我的桌子:

仓库库存

id  |   barcode      |  quantity  | warehouse_id
-------------------------------------------------
1   | 2211345661     | 21         | 1
2   | 2211345661     | 2          | 2
3   | 3452543234     | 1          | 2
4   | 3452543235     | 1          | 1
5   | 3452543236     | 1          | 1
6   | 3452543242     | 1          | 1
7   | 3452543245     | 1          | 1
8   | 3452543245     | 1          | 3
9   | 3452543245     | 1          | 1

product_variants

id    | ean(barcode)     | product_id
-------------------------------------
1     | 3452543245       | 14
2     | 3452543234       | 15
3     | 3452543245       | 16
4     | 3452543245       | 17
5     | 2211345661       | 18
6     | 2211345661       | 19

产品

id     |   name     |   color  | manufacturer_id
------------------------------------------------
14     | Sample 1   | Red      | 1
15     | Sample 2   | Black    | 1
16     | Sample 3   | White    | 1
17     | Sample 4   | White    | 1
18     | Sample 5   | Orange   | 2
19     | Sample 6   | Pink     | 2

我只想显示SUM(quantity)product.namebarcodemanufacturer_idwarehouse_id。除了条形码编号之外没有任何关系。

这是我的代码:

SELECT 
    SUM(ws.quantity) AS total_q,
    p.name,
    ws.barcode,
    p.manufacturer_id,
    ws.warehouse_id
FROM warehouse_stock AS ws
    INNER JOIN product_variants AS pv ON pv.ean = ws.barcode
    INNER JOIN products AS p ON p.id = pv.product_id
WHERE ws.warehouse_id = 1 AND p.manufacturer_id = 1
GROUP BY ws.barcode

它有效,但主要是因为该查询已关闭。然后我们必须重新启动它。

如何更改它以使用子查询?

PS:sql 上没有索引。并且没有索引权限。所以,我想要你的建议。对于这样的查询,子查询可能比 JOIN 更好。

【问题讨论】:

  • 主要问题是缺少索引
  • 你能在查询上运行 EXPLAIN 并发布吗?
  • 第一个问题和提高性能最简单最好的方法:“sql 上没有索引。”第二:AND ws.stock_location_id = 1181的重复是怎么回事?第三:JOINs 几乎总是比子查询快。我不确定是不是故意的,但如果一个产品有四个变体,数量将被计算四次。
  • 表上的字段比较多,但是上面我没写。
  • 所有表 sendspace.com/filegroup/vlBktwpCXIAf2SnWe%2B2XYaXmP7SjFWIb 编辑:@G-Nugget 抱歉 ws.stock_location_id 被多次复制,idk 为什么...我修复了它...

标签: mysql sql join subquery


【解决方案1】:

与其重写查询以使用子查询,不如只在warehouse_stock.warehouse_idproduct_variants.ean 上添加索引应该没问题。由于将使用索引,查询将运行得更快。如果查询使用子查询,它会更慢。

此外,由于您只是在ws.barcode 上使用GROUP BY,因此行包含来自多个products 的信息,因此p.name 仅显示组中的第一个产品名称。每行不代表具体产品的计数,而是具体barcode 的计数,可能涵盖多个products,因此p.name 在行中可能会产生误导。

【讨论】:

  • 问题是,我们不允许添加索引。我完全同意你的看法。但是一定有办法吗?除了 GROUP_CONCAT(p.name) 之外,你 seggest 什么?谢谢。
  • GROUP_CONCAT(p.name) 将向您显示所有产品名称,但如果您需要为每个产品而不是每个 barcode 单独计数,您应该 GROUP BY product_id。如果不能添加索引,您将无法显着提高查询的性能;表需要索引。让它使用子查询可能会使其变慢。
猜你喜欢
  • 2021-12-06
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多