2014-11-16 2 views
0

Я новичок в управлении нашим sqserver db. получил эту просьбу.sql server 2008 медленный запрос на сумму

У меня есть большой стол с миллионом записей. Хотелось бы запустить этот отчет. Он занимает более часа с использованием 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 
+2

Этот метод расчета текущих итогов не масштабируется до 1 миллиона строк. –

ответ

0

Я думаю, что это будет работать быстрее:

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 
+1

У него будет такая же проблема, как у OP. Проблема состоит в том, что 1 000 000 групп будут в среднем по каждому значению 'SUM' 500 000. Суммируется сумма в 500 миллиардов. –

+0

Я не пробовал, но, возможно, удалял, где предложение и размещение этого условия в соединении помогает для скорости. –

+0

Я думал, что SUM, выраженный как подвыбор, будет медленнее, чем более прямой подход сгруппированного запроса. – JohnS

2

Это все гораздо проще в 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); 
+0

Это то, что сработало. Я добавил указанный выше индекс. CREATE INDEX ON IX ТПС (VarcharField, DX) ВКЛЮЧИТЬ (ROWID, QC) Select T1.VarcharField, T1.DX, t1.rowid, \t Итого = \t \t ( \t \t \t SELECT SUM (t2.QC) как общая ОТ TBL t2 \t \t \t WHERE t2.VarcharField = T1.VarcharField \t \t \t и t2.dx <= t1.dx \t \t \t и t2.rowid = t1.rowid \t \t) FROM tbl AS T1 ORDER BY DX, VarcharField, rowid – kdigman

+0

@kdigman добавив, что 't2.rowid = t1.rowid' значительно изменит семантику. –

Смежные вопросы