Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server sql server 2008对总和的慢速查询_Sql Server_Sql Server 2008_Cumulative Sum - Fatal编程技术网

Sql server sql server 2008对总和的慢速查询

Sql server sql server 2008对总和的慢速查询,sql-server,sql-server-2008,cumulative-sum,Sql Server,Sql Server 2008,Cumulative Sum,我对管理sqlserver数据库还不熟悉。我收到了这个请求 我有一张有一百万张唱片的大桌子。要运行此报告。使用SQL Server 2008需要一个多小时 Rowid是PK,在dx和varcharfield上有一个索引 SELECT T1.VarcharField, T1.DX, T1.ROWID, (SELECT Sum(t2.QC) AS Total FROM tbl t2 WHERE T2.VarcharFie

我对管理sqlserver数据库还不熟悉。我收到了这个请求

我有一张有一百万张唱片的大桌子。要运行此报告。使用SQL Server 2008需要一个多小时

Rowid是PK,在dx和varcharfield上有一个索引

SELECT T1.VarcharField,
       T1.DX,
       T1.ROWID,
       (SELECT Sum(t2.QC) AS Total
        FROM   tbl t2
        WHERE  T2.VarcharField = T1.VarcharField
               AND t2.dx <= t1.dx) AS Total
FROM   tbl AS T1 

我认为这将运行得更快:

SELECT
  T1.VarcharField,
  T1.DX,
  T1.ROWID,
  SUM(t2.QC) AS Total
FROM
  tbl t2
  JOIN tb1 T1 ON T2.VarcharField = T1.VarcharField
GROUP BY 
  T1.VarcharField,
  T1.DX,
  T1.ROWID
WHERE
  t2.dx <= t1.dx

在SQL Server 2012中,这一点要容易得多

SELECT T1.VarcharField,
       T1.DX,
       T1.ROWID,
       SUM(QC) OVER (PARTITION BY VarcharField ORDER BY DX) AS Total
FROM   tbl AS T1 
由于您在2008年,上述语法不起作用,您可以尝试添加此索引

CREATE INDEX ix ON tbl(VarcharField,DX) INCLUDE (ROWID, QC)
然后使用以下查询

WITH RecursiveCTE
     AS (SELECT VarcharField,
                DX,
                ROWID,
                QC,
                QC AS Total
         FROM   (SELECT *,
                        ROW_NUMBER() OVER (PARTITION BY VarcharField ORDER BY DX) AS RN
                 FROM   tbl) T
         WHERE  RN = 1
         UNION ALL
         SELECT R.VarcharField,
                R.DX,
                R.ROWID,
                R.QC,
                R.Total
         FROM   (SELECT T.*,
                        T.QC + Total AS Total,
                        rn = ROW_NUMBER() OVER (ORDER BY T.DX)
                 FROM   tbl T
                        JOIN RecursiveCTE R
                          ON R.VarcharField = T.VarcharField
                             AND R.DX < T.DX) R
         WHERE  R.rn = 1)
SELECT VarcharField,
       DX,
       ROWID,
       Total
FROM   RecursiveCTE
OPTION (MAXRECURSION 0); 

这种计算运行总计的方法不能扩展到100万行。它将遇到与OP相同的问题。问题是1000000个组平均每个组将合计500000个值。总计有5000亿个值被求和。我没有尝试过,但可能删除where子句并将该条件置于join中有助于提高速度。我认为表示为子选择的求和比分组查询更直接的方法要慢。这就是有效的方法。我添加了上述索引。在tblVarcharField上创建索引ix,DX INCLUDE ROWID,QC选择T1.VarcharField,T1.DX,T1.ROWID,Total=从tbl t2中选择Sumt2.QC作为总计,其中t2.VarcharField=T1.VarcharField和t2.DX@kdigman添加t2.ROWID=T1.ROWID将极大地改变语义。