[英]Need Help optimizing a complex MySQL query
我在下面有这个查询。 涉及4个主要表:tblOrder,tblItems,tblOrder_archive,tblItem_archive。 几个月后,订单和项目将移至表的存档版本,以免减慢主表查询的速度。 (销售和流量确实很高)。 因此,要获取销售数字,我从每组表中选择所需的文件(存档和非存档)..将它们合并..对联合进行分组..然后对结果进行一些数学运算。
问题在于,如果有大量行(排序时间跨度),查询将花费很长时间运行,从而超时。 我添加了所有我能想到的键,但运行起来仍然非常慢。
我还能做些什么来加快运行速度吗? 我可以改写吗? 我可以使用不同的索引吗?
还是我应该编写一个脚本,该脚本首先从每个表集中获取数据,然后php脚本中的数学将它们组合起来?
谢谢您的帮助。
SELECT
description_invoice
, supplier
, type
, sum(quantity) AS num_sold
, sum(quantity*wholesale) AS wholesale_price
, sum(quantity*price) AS retail_price
, sum(quantity*price) - sum(quantity*wholesale) AS profit
FROM (
SELECT
tblOrder.*
, tblItem.description_invoice
, tblItem.type
, tblItem.product_number
, tblItem.quantity
, tblItem.wholesale
, tblItem.price
, tblItem.supplier
FROM tblOrder USE KEY (finalized), tblItem
WHERE
tblItem.order_id = tblOrder.order_id
AND
finalized=1
AND
wholesale <> 0
AND (order_time >= 1251788400 AND order_time <= 1283669999)
UNION
SELECT
tblOrder_archive.*
, tblItem_archive.description_invoice
, tblItem_archive.type
, tblItem_archive.product_number
, tblItem_archive.quantity
, tblItem_archive.wholesale
, tblItem_archive.price
, tblItem_archive.supplier
FROM tblOrder_archive USE KEY (finalized), tblItem_archive
WHERE
tblItem_archive.order_id=tblOrder_archive.order_id
AND
finalized=1
AND
wholesale <> 0
AND (order_time >= 1251788400 AND order_time <= 1283669999)
) AS main_table
GROUP BY
description_invoice
, supplier,type
ORDER BY profit DESC;
我将您的查询重新编写为:
SELECT COALESCE(x.description_invoice, y.description_invoice) AS description_invoice,
COALESCE(x.supplier, y.supplier) AS supplier,
COALESCE(x.type, y.type) AS type,
COALESCE(SUM(x.quantity), 0) + COALESCE(SUM(y.quantity), 0) as num_sold,
COALESCE(SUM(x.quantity * x.wholesale), 0) + COALESCE(SUM(y.quantity * y.wholesale), 0) AS wholesale_price,
COALESCE(SUM(x.quantity * x.price), 0) + COALESCE(SUM(y.quantity * y.price), 0) AS retail_price,
COALESCE(SUM(x.quantity * x.price), 0) - COALESCE(SUM(x.quantity * x.wholesale), 0) + COALESCE(SUM(y.quantity * y.price), 0) - COALESCE(SUM(y.quantity * y.wholesale), 0) as profit
FROM (SELECT o.order_id
FROM TBLORDER o
WHERE o.finalized = 1
AND o.order_time BETWEEN 1251788400
AND 1283669999
UNION ALL
SELECT oa.order_id
FROM TBLORDER_ARCHIVE oa
WHERE oa.finalized = 1
AND oa.order_time BETWEEN 1251788400
AND 1283669999) a
LEFT JOIN TBLITEM x ON x.order_id = a.order_id
AND x.wholesale != 0
LEFT JOIN TBLITEM_ARCHIVE y ON y.order_id = a.order_id
AND y.wholesale != 0
GROUP BY description_invoice, supplier, type
ORDER BY profit DESC
UNION
,但我希望不需要从存档表中删除重复项,因此我将其更改为UNION ALL
速度更快,因为它不会删除重复项 SELECT ORDERS.*
和SELECT ORDER_ARCHIVE.*
但从未使用任何列。 TBLITEM
表上,该表不必要在派生表/内联视图内。 USE KEY(finalized)
; 您可以根据需要将其重新添加,但是我想与它进行比较-我建议在运行查询之前在两个表上偶尔运行ANALYZE TABLE ,以便优化器具有相对较新的统计信息。 我在finalized
列的索引中看不到太多价值,但是我不知道您的数据或使用情况—仅此查询。 但是基于此查询,我将索引:
...作为覆盖索引-按提供的顺序包含三列的单个索引,因为顺序在覆盖索引中很重要。
我根据您的帮助将其重写如下,并向tblOrder和tblOrder归档文件中添加了推荐的覆盖索引,并且一切似乎都快得多。 但是,我仍然想知道您编写它的方式是否还有其他内容。.但是我还需要使用tblItem_archive和tblOrder_archive一起加入。
SELECT
description_invoice
, supplier
, type
, sum(quantity) AS num_sold
, sum(quantity*wholesale) AS wholesale_price
, sum(quantity*price) AS retail_price
, sum(quantity*price) - sum(quantity*wholesale) AS profit
FROM (
SELECT
tblOrder.order_id
, tblItem.description_invoice
, tblItem.type
, tblItem.product_number
, tblItem.quantity
, tblItem.wholesale
, tblItem.price
, tblItem.supplier
FROM tblOrder, tblItem
WHERE
tblItem.order_id = tblOrder.order_id
AND
finalized=1
AND
wholesale <> 0
AND (order_time >= 1251788400 AND order_time <= 1283669999)
UNION ALL
SELECT
tblOrder_archive.order_id
, tblItem_archive.description_invoice
, tblItem_archive.type
, tblItem_archive.product_number
, tblItem_archive.quantity
, tblItem_archive.wholesale
, tblItem_archive.price
, tblItem_archive.supplier
FROM tblOrder_archive, tblItem_archive
WHERE
tblItem_archive.order_id=tblOrder_archive.order_id
AND
finalized=1
AND
wholesale <> 0
AND (order_time >= 1251788400 AND order_time <= 1283669999)
) AS main_table
GROUP BY
description_invoice
, supplier,type
ORDER BY profit DESC;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.