压缩速度更快的MySQL总和+;加入
我有一个半复杂的压缩速度更快的MySQL总和+;加入,mysql,sql,Mysql,Sql,我有一个半复杂的JOIN结构,可以根据订单从MySQL数据库中获取特定信息。首先让我给你一个SQL查询 SELECT #orders.*, orders.id, customers.lastname, customers.priority, shipments.status, pmv_sl.productmodelvariant_id, pmv_sl.nr AS pmv_nr, COALESCE(SUM(orderlines.nr)
JOIN
结构,可以根据订单从MySQL数据库中获取特定信息。首先让我给你一个SQL查询
SELECT
#orders.*,
orders.id,
customers.lastname,
customers.priority,
shipments.status,
pmv_sl.productmodelvariant_id,
pmv_sl.nr AS pmv_nr,
COALESCE(SUM(orderlines.nr), 0) AS orderlines_nr_count,
COALESCE(SUM(shipment_lines.nr), 0) AS shipment_lines_nr_count
FROM orders
INNER JOIN customers ON customers.id = orders.customer_id
INNER JOIN platforms ON platforms.id = orders.platform_id
INNER JOIN stocklocations ON stocklocations.id = platforms.stocklocation_id
LEFT JOIN orderlines ON orderlines.order_id = orders.id
LEFT JOIN shipments ON shipments.order_id = orders.id
LEFT JOIN shipment_lines ON shipment_lines.shipment_id = shipments.id
# This JOIN, together with shipment_lines, makes the query suddenly very slow (probably because of all the SUM()'s)
LEFT JOIN productmodelvariants_stocklocations pmv_sl ON
pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
AND pmv_sl.stocklocation_id = stocklocations.id
WHERE
orders.orderstatus_id = 2
AND orders.order_all_to_shipment = 0
GROUP BY
orders.id
问题
所以我计算了这个查询的4种速度(所有情况下都有450个结果)
LEFT-JOIN发货行
和无LEFT-JOIN-productmodelvariants\u库存位置
左连接装运线
左键连接productmodelvariants\u stocklocations
2.
和3.
:24528订单行中的行
- 装运行中的行:6345
中的行:1819productmodelvariants\u stocklocations
2.
和3.
(在4.
)都加入了比赛;SQL开始出汗了
我想知道是否有比我更了解(我的)SQL的人知道一种方法来改变查询的上下文以提高它的性能
我还注意到,当执行4.
并引用合并(SUM()
)时,我很容易获得0.8到1.0
秒
更新
解释扩展
由于未能在shippings.status上指定联接子句,您正在创建交叉联接
尝试按如下方式重新组织查询:
SELECT A.*,
orders_id,
customers.lastname,
customers.priority,
# shipments.status,
pmv_sl.productmodelvariant_id,
pmv_sl.nr AS pmv_nr,
orderlines_nr_count,
shipment_lines_nr_count
FROM (
SELECT
#orders.*,
orders.id AS orders_id,
# shipments.status,
COALESCE(SUM(orderlines.nr), 0) AS orderlines_nr_count,
COALESCE(SUM(shipment_lines.nr), 0) AS shipment_lines_nr_count
FROM orders
LEFT JOIN orderlines ON orderlines.order_id = orders.id
LEFT JOIN shipments ON shipments.order_id = orders.id
LEFT JOIN shipment_lines ON shipment_lines.shipment_id = shipments.id
WHERE orders.orderstatus_id = 2
AND orders.order_all_to_shipment = 0
GROUP BY
orders.id,
orderlines.productmodelvariant_id,
stocklocations.id
) orders
INNER JOIN customers ON customers.id = orders.customer_id
INNER JOIN platforms ON platforms.id = orders.platform_id
INNER JOIN stocklocations ON stocklocations.id = platforms.stocklocation_id
LEFT JOIN productmodelvariants_stocklocations pmv_sl ON
pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
AND pmv_sl.stocklocation_id = stocklocations.id
GROUP BY
orders.id
然后找出装运状态的位置。您没有在shippings.status上指定join子句,这是在创建交叉联接
尝试按如下方式重新组织查询:
SELECT A.*,
orders_id,
customers.lastname,
customers.priority,
# shipments.status,
pmv_sl.productmodelvariant_id,
pmv_sl.nr AS pmv_nr,
orderlines_nr_count,
shipment_lines_nr_count
FROM (
SELECT
#orders.*,
orders.id AS orders_id,
# shipments.status,
COALESCE(SUM(orderlines.nr), 0) AS orderlines_nr_count,
COALESCE(SUM(shipment_lines.nr), 0) AS shipment_lines_nr_count
FROM orders
LEFT JOIN orderlines ON orderlines.order_id = orders.id
LEFT JOIN shipments ON shipments.order_id = orders.id
LEFT JOIN shipment_lines ON shipment_lines.shipment_id = shipments.id
WHERE orders.orderstatus_id = 2
AND orders.order_all_to_shipment = 0
GROUP BY
orders.id,
orderlines.productmodelvariant_id,
stocklocations.id
) orders
INNER JOIN customers ON customers.id = orders.customer_id
INNER JOIN platforms ON platforms.id = orders.platform_id
INNER JOIN stocklocations ON stocklocations.id = platforms.stocklocation_id
LEFT JOIN productmodelvariants_stocklocations pmv_sl ON
pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
AND pmv_sl.stocklocation_id = stocklocations.id
GROUP BY
orders.id
然后找出发货状态的位置。您的查询是对任何给定的订单在订单和发货之间进行笛卡尔联接。更好的方法是在进行联接之前,将所有内容汇总到订单id
级别:
SELECT
#orders.*,
orders.id,
customers.lastname,
customers.priority,
shipments.status,
pmv_sl.productmodelvariant_id,
pmv_sl.nr AS pmv_nr,
COALESCE(ol.orderlines_nr_count, 0) AS orderlines_nr_count,
COALESCE(sl.shipment_lines_nr_count, 0) AS shipment_lines_nr_count
FROM orders
INNER JOIN customers ON customers.id = orders.customer_id
INNER JOIN platforms ON platforms.id = orders.platform_id
INNER JOIN stocklocations ON stocklocations.id = platforms.stocklocation_id
LEFT JOIN
(select order_id, SUM(orderlines.nr) as orderline_nr_count
from orderlines
group by order_id
) ol ON ol.order_id = orders.id
LEFT JOIN shipments ON shipments.order_id = orders.id
LEFT JOIN
(select order_id, SUM(shipment_lines.nr) shipment_lines_nr_count
from shipment_lines
group by order_id
) sl ON sl.shipment_id = shipments.id
# This JOIN, together with shipment_lines, makes the query suddenly very slow (probably because of all the SUM()'s)
LEFT JOIN productmodelvariants_stocklocations pmv_sl ON
pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
AND pmv_sl.stocklocation_id = stocklocations.id
WHERE
orders.orderstatus_id = 2
AND orders.order_all_to_shipment = 0
GROUP BY
orders.id
这是一个近似值,因为我看到的唯一聚合函数是针对订单行和发货行的。例如,如果每个订单有多个发货,则必须找出如何将其压缩到一个状态(原始查询将任意选择一个,此查询也是如此)
如果您仅在订单id
级别将表/子查询联接在一起,则最终的分组依据将是不必要的。对于任何给定的订单,您的查询在订单和装运之间进行笛卡尔联接。更好的方法是在联接之前将所有内容汇总到订单id
级别:
SELECT
#orders.*,
orders.id,
customers.lastname,
customers.priority,
shipments.status,
pmv_sl.productmodelvariant_id,
pmv_sl.nr AS pmv_nr,
COALESCE(ol.orderlines_nr_count, 0) AS orderlines_nr_count,
COALESCE(sl.shipment_lines_nr_count, 0) AS shipment_lines_nr_count
FROM orders
INNER JOIN customers ON customers.id = orders.customer_id
INNER JOIN platforms ON platforms.id = orders.platform_id
INNER JOIN stocklocations ON stocklocations.id = platforms.stocklocation_id
LEFT JOIN
(select order_id, SUM(orderlines.nr) as orderline_nr_count
from orderlines
group by order_id
) ol ON ol.order_id = orders.id
LEFT JOIN shipments ON shipments.order_id = orders.id
LEFT JOIN
(select order_id, SUM(shipment_lines.nr) shipment_lines_nr_count
from shipment_lines
group by order_id
) sl ON sl.shipment_id = shipments.id
# This JOIN, together with shipment_lines, makes the query suddenly very slow (probably because of all the SUM()'s)
LEFT JOIN productmodelvariants_stocklocations pmv_sl ON
pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
AND pmv_sl.stocklocation_id = stocklocations.id
WHERE
orders.orderstatus_id = 2
AND orders.order_all_to_shipment = 0
GROUP BY
orders.id
这是一个近似值,因为我看到的唯一聚合函数是针对订单行和发货行的。例如,如果每个订单有多个发货,则必须找出如何将其压缩到一个状态(原始查询将任意选择一个,此查询也是如此)
如果您仅在订单id
级别将表/子查询连接在一起,那么最终的分组依据将是不必要的。您是否在发货行上有索引。nr
和订单行。nr
?如果有,是什么类型的索引?只是一个问题。很好的一点;我的主要和相对id上只有索引。你认为它会有多大的影响?我不希望它会对这些表的总体性能产生太大的影响,因为这主要是添加太多索引的问题:PI已经将索引添加到两个表的nr
字段中。遗憾的是,速度没有提高。甚至完全一样。编辑:添加到nr
ode>productmodelvariants\u stocklocations
也一样。也没有改进。您确定在这种情况下需要使用左连接吗?是的,否则一些想要的结果将被排除。此外,即使我将它们全部设置为内部
进行测试。我返回了219
行,遗憾的是,它们仍然运行3.825秒
。因此相对而言,它是n甚至是一个很大的收获。你在发货行.nr
和订单行.nr
上有索引吗?如果有,是什么类型的索引?只是一个问题。很好的观点;我只在我的主ID和相对ID上有索引。你认为它会有多大的影响?我不希望它会对这些表的总体性能产生太大的影响,a这主要是添加太多索引的问题:PI已经将索引添加到两个表的nr
字段中。遗憾的是,速度没有提高。甚至完全相同。编辑:也添加到productmodelvariants\u stocklocations
的nr
。也没有改进。您确定需要使用左连接i吗在这种情况下?是的,否则一些想要的结果将被排除在外。而且,即使我将它们全部设置为内部
进行测试。我返回了219行
行,它们仍然运行3.825秒
。很遗憾,相对而言,这算不上什么大的收益。感谢您的回答!出于某种奇怪的原因,之后的第一个内部联接
(…)订单
失败(customers.id=orders.customer\u id
)(错误代码1054)。它们无法连接?子选择必须在所选字段中的SELECT子句中包含客户id。(选择orders.customer\u id作为客户id,…)订单内部连接…
对平台id执行与我建议的客户id相同的操作错误代码:1054。“on子句”中的未知列“orderlines.productmodelvariant\u id”
。我在SELECT子句中执行了此操作orderlines.productmodelvariant\u id作为productmodelvariant\u id,
,但它没有抓住它。感谢您的回答!由于某种奇怪的原因,(…)订单之后的第一个内部联接
失败(customers.id=orders.customer\u id
)(错误代码1054)。它们无法连接?子选择必须在