Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ускорение insert в таблицу / 11 сообщений из 11, страница 1 из 1
26.11.2018, 11:38
    #39738432
ondorsal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
Коллеги, проблема.
Есть процедура, которая циклом вставляет данные в таблицу MSSQL 2014 Developer. За одну итерацию 12-40к строк.
Всего процедура обрабатывает ~90 млн строк за 48 минут. В таблице для вставки нет индексов, у базы модель восстановления Simple.
В плане запроса ~80% ресурсов приходитcя на этот insert.

Уже делал:
1). Секционирование таблицы, в которую вставляются данные, по годам с параллельным запуском этой процедуры с разными диапазонами дат.
2). Перевод этой таблицы в InMemory.
Помогло слабо.
Что еще можно попробовать?
...
Рейтинг: 0 / 0
26.11.2018, 11:41
    #39738437
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
ondorsal,

Референсы есть?
...
Рейтинг: 0 / 0
26.11.2018, 11:55
    #39738443
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
ondorsalу базы модель восстановления Simple.ondorsalЧто еще можно попробовать?insert с минимальным журналированием.
...
Рейтинг: 0 / 0
26.11.2018, 12:07
    #39738458
ondorsal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
TaPaK, текст процедуры. Reference в ней нет.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
ALTER PROCEDURE [dbo].[Load] 

@ss as datetime,
@ss2 as datetime
as

while @ss<=@ss2
begin
WITH CTE AS(SELECT @ss as YMD
       ,T.[ProductID]
      ,T.[SkladId]
      ,T.[DocGroupId]
, Sum(T.InOut)as EndRest
	    FROM [DB].[dbo].[TempFact] as T with(nolock)
  where T.[YMD] <= @ss 
  group by T.[ProductID]
      ,T.[SkladId]
      ,T.[DocGroupId])

insert into DoNotTouch
select L.YMD,L.ProductId,L.SkladId,L.DocGroupId, (L.EndRest-isnull(R.InOut,0)) as BegRest, isnull(R.InOut,0) as InOut,L.EndRest
from(
SELECT @ss as YMD
      ,T.[ProductID]
      ,T.[SkladId]
      ,T.[DocGroupId]
      ,T.EndRest
	    FROM CTE as T with(nolock)
  where T.[YMD]<=@ss) as L left outer join [DB].[dbo].[TempFact] as R with(nolock)
	   on L.ProductId=R.ProductId
	 and L.YMD=R.[YMD]
     and L.SkladId=R.SkladId 
     and L.DocGroupId=R.DocGroupId
	 where abs(isnull(R.InOut,0))>0 

union all

select L.YMD,L.ProductId,L.SkladId,570060 as DocGroupId,
sum((L.EndRest-isnull(R.InOut,0))) as BegRest, Sum(isnull(R.InOut,0)) as InOut, sum(L.EndRest) as EndRest
from(
SELECT @ss as YMD
       ,T.[ProductID]
      ,T.[SkladId]
      ,T.[DocGroupId]
      ,T.EndRest
	    FROM CTE as T with(nolock)
  where T.[YMD]<=@ss) as L left outer join [DB].[dbo].[TempFact] as R with(nolock)
	   on L.ProductId=R.ProductId
	 and L.YMD=R.[YMD]
     and L.SkladId=R.SkladId 
     and L.DocGroupId=R.DocGroupId
	 where isnull(R.InOut,0)=0  and  (abs(isnull(R.InOut,0)) + abs(L.EndRest))>0
	 group by L.YMD,L.ProductId,L.SkladId
having abs(sum(isnull(R.InOut,0)))+abs(sum(L.EndRest))>0

option (maxdop 0)
  set @ss=@ss+1
  end	
  
GO
...
Рейтинг: 0 / 0
26.11.2018, 12:13
    #39738463
a_voronin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
ondorsalКоллеги, проблема.
Есть процедура, которая циклом вставляет данные в таблицу MSSQL 2014 Developer. За одну итерацию 12-40к строк.
Всего процедура обрабатывает ~90 млн строк за 48 минут. В таблице для вставки нет индексов, у базы модель восстановления Simple.
В плане запроса ~80% ресурсов приходитcя на этот insert.

Уже делал:
1). Секционирование таблицы, в которую вставляются данные, по годам с параллельным запуском этой процедуры с разными диапазонами дат.
2). Перевод этой таблицы в InMemory.
Помогло слабо.
Что еще можно попробовать?


Загружайте в InMemory несколькими параллельными потоками. На одном потоке выигрыша не увидите.
...
Рейтинг: 0 / 0
26.11.2018, 12:17
    #39738467
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
ondorsal,

автор текст процедуры
действительно, дело во вставке...
...
Рейтинг: 0 / 0
26.11.2018, 13:34
    #39738539
AlanDenton
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
Попробуйте что-то такое:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
ALTER PROCEDURE [dbo].[Load]
(
      @ss AS DATETIME
    , @ss2 AS DATETIME
)
AS BEGIN

    WHILE @ss <= @ss2 BEGIN
        
        IF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL
            DROP TABLE #temp

        SELECT @ss AS YMD
             , T.[ProductID]
             , T.[SkladId]
             , T.[DocGroupId]
             , SUM(T.InOut) AS EndRest
        INTO #temp
        FROM [DB].[dbo].[TempFact] AS T WITH (NOLOCK)
        WHERE T.[YMD] <= @ss
        GROUP BY T.[ProductID]
               , T.[SkladId]
               , T.[DocGroupId]

        IF OBJECT_ID('tempdb.dbo.#temp2') IS NOT NULL
            DROP TABLE #temp2

        SELECT R.ProductId
             , R.[YMD]
             , R.SkladId
             , R.DocGroupId
             , R.InOut
        INTO #temp2
        FROM [DB].[dbo].[TempFact] AS R WITH (NOLOCK)
        WHERE R.[YMD] = @ss

        INSERT INTO DoNotTouch
        SELECT L.YMD
             , L.ProductId
             , L.SkladId
             , L.DocGroupId
             , (L.EndRest - ISNULL(R.InOut, 0)) AS BegRest
             , ISNULL(R.InOut, 0) AS InOut
             , L.EndRest
        FROM #temp AS L
        LEFT JOIN #temp2 ON L.ProductId = R.ProductId AND L.SkladId = R.SkladId AND L.DocGroupId = R.DocGroupId
        WHERE ABS(ISNULL(R.InOut, 0)) > 0

        UNION ALL

        SELECT L.YMD
             , L.ProductId
             , L.SkladId
             , 570060 AS DocGroupId
             , SUM((L.EndRest - ISNULL(R.InOut, 0))) AS BegRest
             , SUM(ISNULL(R.InOut, 0)) AS InOut
             , SUM(L.EndRest) AS EndRest
        FROM #temp AS L
        LEFT JOIN #temp2 ON L.ProductId = R.ProductId AND L.SkladId = R.SkladId AND L.DocGroupId = R.DocGroupId
        WHERE ISNULL(R.InOut, 0) = 0
            AND (ABS(ISNULL(R.InOut, 0)) + ABS(L.EndRest)) > 0
        GROUP BY L.YMD
               , L.ProductId
               , L.SkladId
        HAVING ABS(SUM(ISNULL(R.InOut, 0))) + ABS(SUM(L.EndRest)) > 0
        OPTION (MAXDOP 0)

        SET @ss = @ss + 1

    END

END


Плюс вечный вопрос: какие индексы на той таблице из которой вы данные выгребаете? По хорошему должен быть индекс по полю YMD на первом месте и остальное как часть кластерного индекса либо в INCLUDED
...
Рейтинг: 0 / 0
26.11.2018, 14:23
    #39738585
ondorsal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
AlanDenton, индексы такие
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE CLUSTERED INDEX [IX] ON [dbo].[TempFact]
(
	[ProductID] ASC,
	[YMD] ASC,
	[SkladId] ASC,
	[DocGroupId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO



Код: sql
1.
2.
3.
4.
5.
CREATE NONCLUSTERED COLUMNSTORE INDEX [IXCOL] ON [dbo].[TempFact]
(
	[InOut]
)WITH (DROP_EXISTING = OFF) ON [PRIMARY]
GO
...
Рейтинг: 0 / 0
26.11.2018, 14:29
    #39738590
dvim
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
ondorsal,
Я бы шел в сторону bcp или Tabled параметров.
Быстрее этого в природе ничего нет.
...
Рейтинг: 0 / 0
26.11.2018, 14:30
    #39738591
AlanDenton
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
Код: sql
1.
2.
[ProductID] ASC,
	[YMD] ASC,


местами поменяйте и радуйтесь) ибо предикейт пушдаун работать не будет + почитайте за TraceFlag 610 (хотя мне кажется что проблема у вас как раз из-за лишних IndexScan-ов на TempFact)
...
Рейтинг: 0 / 0
27.11.2018, 07:43
    #39738900
Androgen1985
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ускорение insert в таблицу
dvimondorsal,
Я бы шел в сторону bcp или Tabled параметров.
Быстрее этого в природе ничего нет.

А bcp может работать с таблицами?
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ускорение insert в таблицу / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]