【发布时间】:2017-03-26 21:44:50
【问题描述】:
我有一个案例,我需要从包含大量聚合数据的表中收集销售统计数据。该表有几百万个条目,数据库本身约为 22Gb。大量数据可供使用!
我有这个有效的查询,但我觉得我应该做得更好 - 而且它也很慢。
我在 CentOS 7 上使用带有 sqlsrv 扩展的 PHP 连接到 MSSQL 数据库(ERP 系统)。
我在这个查询中的 php 变量是这样设置的:
$customer = '12345';
$year = '2016';
$compared_year = '2015';
所以,正如您可能已经猜到的那样,我正在收集 2016 年和 2015 年每个月的给定客户的销售统计数据。
SELECT
ProdTr.CustNo AS customernummer,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "01' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_1,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "02' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_2,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "03' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_3,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "04' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_4,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "05' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_5,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "06' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_6,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "07' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_7,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "08' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_8,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "09' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_9,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "10' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_10,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "11' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_11,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $year . "12' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS sum_period_12,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "01' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_1,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "02' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_2,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "03' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_3,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "04' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_4,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "05' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_5,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "06' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_6,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "07' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_7,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "08' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_8,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "09' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_9,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "10' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_10,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "10' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_11,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $year . "11' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS dg_period_12,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "01' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_1,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "02' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_2,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "03' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_3,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "04' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_4,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "05' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_5,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "06' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_6,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "07' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_7,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "08' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_8,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "09' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_9,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "10' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_10,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "11' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_11,
(SELECT SUM(DAm) AS 'Sum' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "12' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_sum_period_12,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "01' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_1,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "02' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_2,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "03' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_3,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "04' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_4,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "05' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_5,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "06' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_6,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "07' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_7,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "08' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_8,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "09' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_9,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "10' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_10,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "11' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_11,
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM ProdTr WHERE AcYrPr = '" . $compared_year . "12' AND ProdTr.TrTp = 1 AND ProdTr.CustNo = '" . $customer . "') AS compared_dg_period_12
FROM ProdTr
WHERE AcYrPr LIKE 201612
AND ProdTr.TrTp = 1
AND ProdTr.CustNo = '" . $customer . "'
GROUP BY ProdTr.CustNo, ProdTr.TrTp, ProdTr.AcYrPr
请注意,查询运行良好,给出了我期望的结果 - 但对于有很多订单/交易的客户来说,它太慢了。
关于如何加快速度的任何指示?
非常感谢您的宝贵时间!
【问题讨论】:
-
你看过 GROUP BY 吗?即使你不能在一个查询中运行整个事情,你也可以在一个查询中完成,比如说,四个并将结果放入一个关联数组中。
标签: php sql sql-server