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

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

Референсы есть?
...
Рейтинг: 0 / 0
Ускорение insert в таблицу
    #39738443
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ondorsalу базы модель восстановления Simple.ondorsalЧто еще можно попробовать?insert с минимальным журналированием.
...
Рейтинг: 0 / 0
Ускорение insert в таблицу
    #39738458
ondorsal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Ускорение insert в таблицу
    #39738463
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ondorsalКоллеги, проблема.
Есть процедура, которая циклом вставляет данные в таблицу MSSQL 2014 Developer. За одну итерацию 12-40к строк.
Всего процедура обрабатывает ~90 млн строк за 48 минут. В таблице для вставки нет индексов, у базы модель восстановления Simple.
В плане запроса ~80% ресурсов приходитcя на этот insert.

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


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

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

Код: 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
Ускорение insert в таблицу
    #39738585
ondorsal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
Ускорение insert в таблицу
    #39738590
dvim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ondorsal,
Я бы шел в сторону bcp или Tabled параметров.
Быстрее этого в природе ничего нет.
...
Рейтинг: 0 / 0
Ускорение insert в таблицу
    #39738591
AlanDenton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
[ProductID] ASC,
	[YMD] ASC,


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

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


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