В активной среде SQL Server конкуренция может быть серьезной проблемой при выполнении массовых операций. В предыдущей статье мы обсудили один метод повышения эффективности массовой загрузки путем введения временных таблиц. Однако этот подход просто переносит конкуренцию с основной таблицы на временные таблицы. В этой статье мы рассмотрим, как дальше снизить конкуренцию, избегая дорогостоящих изменений оборудования или перехода на Enterprise Edition.
Ранее мы реализовали процесс, в котором мы переносили массовую вставку в несколько независимых временных таблиц и добавляли фоновый процесс для перемещения данных в основную таблицу. Однако в активной системе веб-серверы, пытающиеся выполнить массовую вставку во время работы фонового процесса, все равно блокировались. Хотя период блокировки был бы короче, мы все равно хотим устранить как можно больше блокировок и конкуренции.
Для решения этой проблемы мы можем создать вторую копию временных таблиц, которую мы назовем “готовой”. Веб-серверы будут продолжать выполнять массовую вставку во временные таблицы, и когда фоновый процесс просыпается, он будет выполнять операцию метаданных для передачи новых данных в готовую таблицу и замены временной таблицы пустой копией. Это снижает конкуренцию, поскольку операция метаданных выполняется быстро и блокирует временную таблицу только на короткое время, не завися от размера данных.
Вот пример того, как это можно реализовать:
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStaging1 FROM dbo.DumpsterTable;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStaging2 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStaging3 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStaging4 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterReady1 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterReady2 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterReady3 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterReady4 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStandby1 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStandby2 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStandby3 FROM dbo.DumpsterStaging1;
SELECT TOP 0 a,b,c,d,e,f,g,h,i,j INTO dbo.DumpsterStandby4 FROM dbo.DumpsterStaging1;
Веб-серверы будут продолжать выполнять массовую вставку во временные таблицы, и фоновый процесс будет выполнять следующие шаги:
ALTER TABLE dbo.DumpsterStaging1 SWITCH TO dbo.DumpsterReady1;
ALTER TABLE dbo.DumpsterStandby1 SWITCH TO dbo.DumpsterStaging1;
-- Повторить для Staging2, Staging3, Staging4
INSERT dbo.DumpsterTable(a,b,c,d,e,f,g,h,i,j) SELECT a,b,c,d,e,f,g,h,i,j FROM dbo.DumpsterReady1;
TRUNCATE TABLE dbo.DumpsterReady1;
ALTER TABLE dbo.DumpsterReady1 SWITCH TO dbo.DumpsterStandby1;
-- Повторить для Ready2, Ready3, Ready4
Реализуя этот подход, мы значительно снижаем конкуренцию на временных таблицах и улучшаем общую производительность массовых операций. Однако важно отметить, что в активной системе может все равно возникать конкуренция на основной таблице. Если требуется дополнительное смягчение, можно рассмотреть такие варианты, как переход на Enterprise Edition или внедрение групп доступности.
В заключение, используя временные таблицы и реализуя фоновый процесс для передачи данных, мы можем эффективно снизить конкуренцию и улучшить эффективность массовых операций в SQL Server.