WHERE A.SALDO > 0 AND
S.STORE_TYPE = 4 AND
Огромная БД. Оптимизация sql-запроса
размеры таблиц: от 1 млн до 30 млн.
Выполняется очень долго.
SELECT A.ID_GOODS AS ID_GOODS,
S.NO366+convert(varchar,S.ID_STORE) AS ID_NETOBJ,
convert(numeric(10,3),round(SUM(ROUND(A.SALDO / AC.DIVIDER,3)),3)) AS SALDO,
convert(numeric(10,3),round(SUM(ROUND(A.SALDO/AC.DIVIDER,3)*AC.PRICE_DELIVERY_BAS*(1+AC.STAVKA_NDS/100)),3)) AS PRICE_WITH_VAT,
convert(numeric(10,3),round(SUM(ROUND(A.SALDO / AC.DIVIDER,3)* AC.PRICE_DELIVERY_BAS),3)) AS PRICE_WITH_NO_VAT,
AC.TIME_APPLY AS TIME_APPLY,
AC.ID_SUBJECT AS ID_SUPPLIER,
case when isnull(I.VIRTUAL,0) = 0 then 1 else 0 end as VIRTUAL
FROM STORE_SALDO A
INNER JOIN STORE S ON S.ID_STORE = A.ID_STORE
INNER JOIN ARTIKUL_CATALOG AC ON AC.ARTIKUL = A.ARTIKUL
inner join spec_indoc si on si.artikul=ac.artikul
inner join indoc i on i.id_indoc=si.id_indoc
WHERE A.SALDO > 0 AND
S.STORE_TYPE = 4 AND
DATE_SAL <= '#UnloadDate#' AND DATE_NEXT > '#UnloadDate#'
GROUP BY A.ID_GOODS,
S.NO366,
S.ID_STORE,
AC.TIME_APPLY,
AC.ID_SUBJECT,
case when isnull(I.VIRTUAL,0) = 0 then 1 else 0 end
Заранее спасибо.
ЗЫ: таблицы проиндексированы? как?
Вот индексы самой большой таблицы:
CREATE NONCLUSTERED INDEX SS_Idx1
ON dbo.STORE_SALDO(ID_STORE,DATE_SAL,DATE_NEXT,SALDO,ID_GOODS)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_Idx1')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_Idx1 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_Idx1 >>>'
go
CREATE NONCLUSTERED INDEX SS_IND_1
ON dbo.STORE_SALDO(ID_STORE,DATE_SAL,FREE_SALDO,DATE_NEXT,ID_GOODS)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_IND_1')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_IND_1 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_IND_1 >>>'
go
CREATE NONCLUSTERED INDEX SS_IND_2
ON dbo.STORE_SALDO(ID_GOODS,DATE_SAL,FREE_SALDO,DATE_NEXT,ID_STORE)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_IND_2')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_IND_2 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_IND_2 >>>'
go
CREATE NONCLUSTERED INDEX SS_IND_3
ON dbo.STORE_SALDO(DATE_SAL,DATE_NEXT,SALDO,ID_STORE)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_IND_3')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_IND_3 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_IND_3 >>>'
go
CREATE NONCLUSTERED INDEX SS_IND_4
ON dbo.STORE_SALDO(ARTIKUL,ID_STORE,DATE_SAL,DATE_NEXT,FREE_SALDO)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_IND_4')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_IND_4 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_IND_4 >>>'
go
CREATE NONCLUSTERED INDEX SS_IND_5
ON dbo.STORE_SALDO(DATE_SAL,ID_GOODS,DATE_NEXT,SALDO,ID_STORE)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_IND_5')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_IND_5 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_IND_5 >>>'
go
CREATE NONCLUSTERED INDEX SS_IDX_6
ON dbo.STORE_SALDO(ID_STORE,ARTIKUL,PRICE,SALDO,DATE_SAL,DATE_NEXT)
go
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('dbo.STORE_SALDO') AND name='SS_IDX_6')
PRINT '<<< CREATED INDEX dbo.STORE_SALDO.SS_IDX_6 >>>'
ELSE
PRINT '<<< FAILED CREATING INDEX dbo.STORE_SALDO.SS_IDX_6 >>>'
go
Код:
Автор, откройте для себя планы выполнения запросов. Без их анализа - все остальное догадки и тыканье пальцем в небо.
QUERY PLAN FOR STATEMENT 1 (at line 1).
Executed in parallel by coordinating process and 5 worker processes.
STEP 1
The type of query is INSERT.
The update mode is direct.
Executed in parallel by coordinating process and 5 worker processes.
Worktable2 created for REFORMATTING.
FROM TABLE
STORE_SALDO
A
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Executed in parallel with a 5-way hash scan.
Using I/O Size 64 Kbytes for data pages.
With MRU Buffer Replacement Strategy for data pages.
TO TABLE
Worktable2.
STEP 2
The type of query is INSERT.
The update mode is direct.
Executed by coordinating process.
Worktable3 created for REFORMATTING.
FROM TABLE
STORE
S
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 64 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
TO TABLE
Worktable3.
STEP 3
The type of query is SELECT (into Worktable1).
GROUP BY
Evaluate Grouped SUM OR AVERAGE AGGREGATE.
Evaluate Grouped SUM OR AVERAGE AGGREGATE.
Evaluate Grouped SUM OR AVERAGE AGGREGATE.
Executed in parallel by coordinating process and 5 worker processes.
FROM TABLE
spec_indoc
si
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Executed in parallel with a 5-way hash scan.
Using I/O Size 64 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
ARTIKUL_CATALOG
AC
Nested iteration.
Using Clustered Index.
Index : PK_ARTIKUL_CATALOG
Forward scan.
Positioning by key.
Keys are:
ARTIKUL ASC
Using I/O Size 8 Kbytes for index leaf pages.
With LRU Buffer Replacement Strategy for index leaf pages.
Using I/O Size 8 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
indoc
i
Nested iteration.
Using Clustered Index.
Index : PK_INDOC
Forward scan.
Positioning by key.
Keys are:
ID_INDOC ASC
Using I/O Size 8 Kbytes for index leaf pages.
With LRU Buffer Replacement Strategy for index leaf pages.
Using I/O Size 8 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
Worktable2.
Nested iteration.
Using Clustered Index.
Using Clustered Index.
Forward scan.
Positioning by key.
Using I/O Size 64 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
FROM TABLE
Worktable3.
Nested iteration.
Using Clustered Index.
Forward scan.
Positioning by key.
Using I/O Size 8 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
TO TABLE
Worktable1.
Parallel work table merge.
STEP 4
The type of query is SELECT.
Executed by coordinating process.
FROM TABLE
Worktable1.
Nested iteration.
Table Scan.
Forward scan.
Positioning at start of table.
Using I/O Size 64 Kbytes for data pages.
With MRU Buffer Replacement Strategy for data pages.