Ten post zawiera nowe informacje o warunkach wstępnych minimalnie rejestrowanego ładowania zbiorczego podczas używania INSERT...SELECT
do indeksowanych tabel .
Wewnętrzna funkcja, która umożliwia takie przypadki, nazywa się FastLoadContext
. Można go aktywować od SQL Server 2008 do 2014 włącznie za pomocą udokumentowanej flagi śledzenia 610. Od SQL Server 2016 i nowszych, FastLoadContext
jest domyślnie włączone; flaga śledzenia nie jest wymagana.
Bez FastLoadContext
, jedyne wstawki indeksowe, które można minimalnie rejestrować czy te są w puste indeks skupiony bez indeksów wtórnych, jak opisano w drugiej części tej serii. minimalne logowanie warunki dla nieindeksowanych tabel stosu zostały omówione w części pierwszej.
Aby uzyskać więcej informacji, zobacz Przewodnik ładowania wydajności danych i zespół Tiger uwagi dotyczące zmian w zachowaniu SQL Server 2016.
Kontekst szybkiego ładowania
Jako szybkie przypomnienie, RowsetBulk
funkcja (opisana w częściach 1 i 2) umożliwia minimalne logowanie ładunek zbiorczy dla:
- Pusty i niepusty sterta tabele z:
- Blokowanie tabeli; i
- Brak wtórnych indeksów.
- Puste tabele klastrowe , z:
- Blokowanie tabeli; i
- Brak indeksów wtórnych; i
DMLRequestSort=true
na wstawce z indeksem klastrowym operator.
FastLoadContext
ścieżka kodu dodaje obsługę minimalnie rejestrowanych i równoczesne ładunek zbiorczy na:
- Pusty i niepusty zgrupowany indeksy b-drzewa.
- Pusty i niepusty niezgrupowany indeksy b-drzewa utrzymywane przez dedykowane Wstawka indeksująca operator planu.
FastLoadContext
wymaga również DMLRequestSort=true
we wszystkich przypadkach na odpowiednim operatorze planu.
Być może zauważyłeś nakładanie się między RowsetBulk
i FastLoadContext
dla pustych tabel klastrowych bez indeksów wtórnych. TABLOCK
podpowiedź nie jest wymagana z FastLoadContext
, ale nie musi być nieobecne zarówno. W konsekwencji odpowiednia wstawka z TABLOCK
może nadal kwalifikować się do minimalnego logowania przez FastLoadContext
jeśli nie powiedzie się, szczegółowy RowsetBulk
testy.
FastLoadContext
można wyłączyć na SQL Server 2016 przy użyciu udokumentowanej flagi śledzenia 692. Kanał debugowania Extended Event fastloadcontext_enabled
może być używany do monitorowania FastLoadContext
użycie na partycję indeksu (zestaw wierszy). To zdarzenie nie uruchamia się dla RowsetBulk
ładunki.
Mieszane rejestrowanie
Pojedynczy INSERT...SELECT
instrukcja przy użyciu FastLoadContext
może w pełni zalogować kilka wierszy podczas minimalnego logowania inne.
Wiersze są wstawiane jeden na raz przez wstawkę indeksującą operator i w pełni zalogowany w następujących przypadkach:
- Wszystkie wiersze dodane do pierwszego strona indeksu, jeśli indeks był pusty na początku operacji.
- Wiersze dodane do istniejących indeksuj strony.
- Wiersze przeniesione między stronami według podziału strony.
W przeciwnym razie wiersze z uporządkowanego strumienia wstawiania są dodawane do nowej strony przy użyciu zoptymalizowanego i minimalnie rejestrowanego ścieżka kodu. Po zapisaniu jak największej liczby wierszy na nowej stronie jest ona bezpośrednio połączona z istniejącą docelową strukturą indeksu.
Nowo dodana strona niekoniecznie być pełny (choć oczywiście jest to idealny przypadek), ponieważ SQL Server musi uważać, aby nie dodawać wierszy do nowej strony, które logicznie należą do istniejącego strona indeksu. Nowa strona zostanie „włączona” do indeksu jako jednostka, więc nie możemy mieć żadnych wierszy na nowej stronie, które należą do innego miejsca. Jest to głównie problem podczas dodawania wierszy w istniejącego zakresu kluczy indeksu, a nie przed początkiem lub po końcu istniejącego zakresu kluczy indeksu.
To nadal możliwe dodawać nowe strony w istniejący zakres kluczy indeksu, ale nowe wiersze muszą być sortowane wyżej niż najwyższy klucz w poprzednim istniejąca strona indeksu i sortuj niżej niż najniższy klucz w następujących istniejąca strona indeksu. Aby uzyskać największą szansę na osiągnięcie minimalnego rejestrowania w takich okolicznościach upewnij się, że wstawione wiersze nie pokrywają się z istniejącymi wierszami, o ile to możliwe.
Warunki DMLRequestSort
Pamiętaj, że FastLoadContext
można aktywować tylko wtedy, gdy DMLRequestSort
ma wartość prawda dla odpowiedniej wstawki indeksu operatora w planie wykonania.
Istnieją dwie główne ścieżki kodu, które można ustawić DMLRequestSort
do prawdy na płytki indeksowe. Każda ścieżka zwracanie prawdy wystarczy.
1. FOptimizeInsert
sqllang!CUpdUtil::FOptimizeInsert
kod wymaga:
- Ponad 250 wierszy szacowany do wstawienia; i
- Więcej niż 2 strony szacowany wstaw rozmiar danych; i
- Indeks docelowy musi mieć mniej niż 3 strony liści .
Te warunki są takie same jak w przypadku RowsetBulk
na pustym indeksie klastrowym, z dodatkowym wymaganiem nie więcej niż dwóch indeksowanych stron na poziomie liścia. Zwróć uwagę, że odnosi się to do rozmiaru istniejącego indeksu przed wstawką, nie szacowany rozmiar danych do dodania.
Poniższy skrypt jest modyfikacją wersji demonstracyjnej używanej we wcześniejszych częściach tej serii. Pokazuje minimalne logowanie gdy mniej niż trzy strony indeksu są wypełnione przed test INSERT...SELECT
biegi. Schemat tabeli testowej jest taki, że 130 wierszy może zmieścić się na jednej stronie o wielkości 8 KB, gdy wersja wierszy jest wyłączona dla bazy danych. Mnożnik w pierwszym TOP
klauzulę można zmienić, aby określić liczbę istniejących stron indeksowych przed test INSERT...SELECT
jest wykonywany:
IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL BEGIN DROP TABLE dbo.Test; END; GO CREATE TABLE dbo.Test ( id integer NOT NULL IDENTITY CONSTRAINT [PK dbo.Test (id)] PRIMARY KEY, c1 integer NOT NULL, padding char(45) NOT NULL DEFAULT '' ); GO -- 130 rows per page for this table -- structure with row versioning off INSERT dbo.Test (c1) SELECT TOP (3 * 130) -- Change the 3 here CHECKSUM(NEWID()) FROM master.dbo.spt_values AS SV; GO -- Show physical index statistics -- to confirm the number of pages SELECT DDIPS.index_type_desc, DDIPS.alloc_unit_type_desc, DDIPS.page_count, DDIPS.record_count, DDIPS.avg_record_size_in_bytes FROM sys.dm_db_index_physical_stats ( DB_ID(), OBJECT_ID(N'dbo.Test', N'U'), 1, -- Index ID NULL, -- Partition ID 'DETAILED' ) AS DDIPS WHERE DDIPS.index_level = 0; -- leaf level only GO -- Clear the plan cache DBCC FREEPROCCACHE; GO -- Clear the log CHECKPOINT; GO -- Main test INSERT dbo.Test (c1) SELECT TOP (269) CHECKSUM(NEWID()) FROM master.dbo.spt_values AS SV; GO -- Show log entries SELECT FD.Operation, FD.Context, FD.[Log Record Length], FD.[Log Reserve], FD.AllocUnitName, FD.[Transaction Name], FD.[Lock Information], FD.[Description] FROM sys.fn_dblog(NULL, NULL) AS FD; GO -- Count the number of fully-logged rows SELECT [Fully Logged Rows] = COUNT_BIG(*) FROM sys.fn_dblog(NULL, NULL) AS FD WHERE FD.Operation = N'LOP_INSERT_ROWS' AND FD.Context = N'LCX_CLUSTERED' AND FD.AllocUnitName = N'dbo.Test.PK dbo.Test (id)'; GO
Gdy indeks klastrowy jest wstępnie załadowany 3 stronami , wkładka testowa jest w pełni zarejestrowana (rekordy szczegółów dziennika transakcji pominięte z powodu zwięzłości):
Gdy tabela jest wstępnie załadowana tylko 1 lub 2 stronami , wkładka testowa jest minimalnie rejestrowana :
Gdy tabela nie jest wstępnie załadowana z dowolnymi stronami test jest równoważny uruchomieniu demonstracji pustej tabeli klastrowej z części drugiej, ale bez TABLOCK
wskazówka:
Pierwsze 130 wierszy jest w pełni zalogowanych . Dzieje się tak, ponieważ indeks był pusty, zanim zaczęliśmy, a 130 wierszy zmieściło się na pierwszej stronie. Pamiętaj, że pierwsza strona jest zawsze w pełni rejestrowana, gdy FastLoadContext
jest używany, a indeks był wcześniej pusty. Pozostałe 139 wierszy jest wstawianych z minimalnym rejestrowaniem .
Jeśli TABLOCK
wskazówka jest dodawana do wkładki, wszystkie strony są minimalnie rejestrowane (w tym pierwszy), ponieważ puste ładowanie indeksu klastrowego kwalifikuje się teraz do RowsetBulk
mechanizm (kosztem pobrania Sch-M
zamek).
2. FDemandRowsSortedForPerformance
Jeśli FOptimizeInsert
testy nie powiodły się, DMLRequestSort
może nadal mieć wartość prawda przez drugi zestaw testów w sqllang!CUpdUtil::FDemandRowsSortedForPerformance
kod. Te warunki są nieco bardziej złożone, więc przydatne będzie zdefiniowanie niektórych parametrów:
P
– liczba istniejących stron na poziomie liścia w indeksie docelowym .I
– szacowany liczba wierszy do wstawienia.R
=P
/I
(docelowe strony na wstawiony wiersz).T
– liczba partycji docelowych (1 dla niepartycjonowanych).
Logika do określenia wartości DMLRequestSort
jest wtedy:
- Jeśli
P <= 16
zwróć fałsz , w przeciwnym razie :- Jeśli
R < 8
:- Jeśli
P > 524
zwróć prawda , w przeciwnym razie fałsz .
- Jeśli
- Jeśli
R >= 8
:- Jeśli
T > 1
iI > 250
zwróć prawda , w przeciwnym razie fałsz .
- Jeśli
- Jeśli
Powyższe testy są oceniane przez procesor zapytań podczas kompilacji planu. Istnieje warunek końcowy oceniane przez kod silnika pamięci masowej (IndexDataSetSession::WakeUpInternal
) w czasie wykonania:
DMLRequestSort
jest obecnie prawda; iI >= 100
.
Następnie podzielimy całą tę logikę na łatwe do opanowania części.
Ponad 16 istniejących stron docelowych
Pierwszy test P <= 16
oznacza, że indeksy z mniej niż 17 istniejącymi stronami-liście nie będą kwalifikować się do FastLoadContext
za pośrednictwem tej ścieżki kodu. Aby być całkowicie jasnym w tej kwestii, P
to liczba stron na poziomie liścia w indeksie docelowym przed INSERT...SELECT
jest wykonywany.
Aby zademonstrować tę część logiki, wstępnie załadujemy testową tabelę klastrową z 16 stronami danych. Ma to dwa ważne efekty (pamiętaj, że obie ścieżki kodu muszą zwracać false skończyć z fałszem wartość dla DMLRequestSort
):
- Zapewnia, że poprzedni
FOptimizeInsert
test nie powiodło się , ponieważ trzeci warunek nie jest spełniony (P < 3
). P <= 16
warunek wFDemandRowsSortedForPerformance
również nie być spełnione.
Dlatego oczekujemy FastLoadContext
nie włączać. Zmodyfikowany skrypt demonstracyjny to:
IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL BEGIN DROP TABLE dbo.Test; END; GO CREATE TABLE dbo.Test ( id integer NOT NULL IDENTITY CONSTRAINT [PK dbo.Test (id)] PRIMARY KEY, c1 integer NOT NULL, padding char(45) NOT NULL DEFAULT '' ); GO -- 130 rows per page for this table -- structure with row versioning off INSERT dbo.Test (c1) SELECT TOP (16 * 130) -- 16 pages CHECKSUM(NEWID()) FROM master.dbo.spt_values AS SV; GO -- Show physical index statistics -- to confirm the number of pages SELECT DDIPS.index_type_desc, DDIPS.alloc_unit_type_desc, DDIPS.page_count, DDIPS.record_count, DDIPS.avg_record_size_in_bytes FROM sys.dm_db_index_physical_stats ( DB_ID(), OBJECT_ID(N'dbo.Test', N'U'), 1, -- Index ID NULL, -- Partition ID 'DETAILED' ) AS DDIPS WHERE DDIPS.index_level = 0; -- leaf level only GO -- Clear the plan cache DBCC FREEPROCCACHE; GO -- Clear the log CHECKPOINT; GO -- Main test INSERT dbo.Test (c1) SELECT TOP (269) CHECKSUM(NEWID()) FROM master.dbo.spt_values AS SV1 CROSS JOIN master.dbo.spt_values AS SV2; GO -- Show log entries SELECT FD.Operation, FD.Context, FD.[Log Record Length], FD.[Log Reserve], FD.AllocUnitName, FD.[Transaction Name], FD.[Lock Information], FD.[Description] FROM sys.fn_dblog(NULL, NULL) AS FD; GO -- Count the number of fully-logged rows SELECT [Fully Logged Rows] = COUNT_BIG(*) FROM sys.fn_dblog(NULL, NULL) AS FD WHERE FD.Operation = N'LOP_INSERT_ROWS' AND FD.Context = N'LCX_CLUSTERED' AND FD.AllocUnitName = N'dbo.Test.PK dbo.Test (id)';
Wszystkie 269 wierszy jest w pełni rejestrowane zgodnie z przewidywaniami:
Pamiętaj, że bez względu na to, jak wysoko ustawimy liczbę nowych wierszy do wstawienia, powyższy skrypt nigdy produkować minimalne logowanie ze względu na P <= 16
test (i P < 3
test w FOptimizeInsert
).
Jeśli zdecydujesz się uruchomić demo samodzielnie z większą liczbą wierszy, skomentuj sekcję, która pokazuje poszczególne zapisy dziennika transakcji, w przeciwnym razie będziesz czekać bardzo długo, a SSMS może się zawiesić. (Szczerze mówiąc, i tak może to zrobić, ale po co zwiększać ryzyko).
Stosunek stron na wstawiony wiersz
Jeśli jest 17 lub więcej strony liści w istniejącym indeksie, poprzednie P <= 16
test nie zawiedzie. Następna sekcja logiki dotyczy proporcji istniejących stron do nowo wstawionych wierszy . To również musi przejść, aby osiągnąć minimalne logowanie . Przypominamy, że odpowiednie warunki to:
- Współczynnik
R
=P
/I
. - Jeśli
R < 8
:- Jeśli
P > 524
zwróć prawda , w przeciwnym razie fałsz .
- Jeśli
Musimy również pamiętać o ostatecznym teście silnika pamięci masowej dla co najmniej 100 wierszy:
I >= 100
.
Nieco reorganizując te warunki, wszystkie z następujących musi być prawdziwe:
P > 524
(istniejące strony indeksu)I >= 100
(szacunkowa liczba wstawionych wierszy)P / I < 8
(stosunekR
)
Istnieje wiele sposobów na jednoczesne spełnienie tych trzech warunków. Wybierzmy minimalne możliwe wartości dla P
(525) i I
(100) dając R
wartość (525/100) =5,25. To spełnia (R < 8
test), więc spodziewamy się, że ta kombinacja spowoduje minimalne rejestrowanie :
IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL BEGIN DROP TABLE dbo.Test; END; GO CREATE TABLE dbo.Test ( id integer NOT NULL IDENTITY CONSTRAINT [PK dbo.Test (id)] PRIMARY KEY, c1 integer NOT NULL, padding char(45) NOT NULL DEFAULT '' ); GO -- 130 rows per page for this table -- structure with row versioning off INSERT dbo.Test (c1) SELECT TOP (525 * 130) -- 525 pages CHECKSUM(NEWID()) FROM master.dbo.spt_values AS SV1 CROSS JOIN master.dbo.spt_values AS SV2; GO -- Show physical index statistics -- to confirm the number of pages SELECT DDIPS.index_type_desc, DDIPS.alloc_unit_type_desc, DDIPS.page_count, DDIPS.record_count, DDIPS.avg_record_size_in_bytes FROM sys.dm_db_index_physical_stats ( DB_ID(), OBJECT_ID(N'dbo.Test', N'U'), 1, -- Index ID NULL, -- Partition ID 'DETAILED' ) AS DDIPS WHERE DDIPS.index_level = 0; -- leaf level only GO -- Clear the plan cache DBCC FREEPROCCACHE; GO -- Clear the log CHECKPOINT; GO -- Main test INSERT dbo.Test (c1) SELECT TOP (100) CHECKSUM(NEWID()) FROM master.dbo.spt_values AS SV1 CROSS JOIN master.dbo.spt_values AS SV2; GO -- Show log entries SELECT FD.Operation, FD.Context, FD.[Log Record Length], FD.[Log Reserve], FD.AllocUnitName, FD.[Transaction Name], FD.[Lock Information], FD.[Description] FROM sys.fn_dblog(NULL, NULL) AS FD; GO -- Count the number of fully-logged rows SELECT [Fully Logged Rows] = COUNT_BIG(*) FROM sys.fn_dblog(NULL, NULL) AS FD WHERE FD.Operation = N'LOP_INSERT_ROWS' AND FD.Context = N'LCX_CLUSTERED' AND FD.AllocUnitName = N'dbo.Test.PK dbo.Test (id)';
100-wierszowy INSERT...SELECT
jest rzeczywiście minimalnie rejestrowany :
Zmniejszenie szacowanego wstawiono wiersze do 99 (przełamując I >= 100
) i/lub zmniejszenie liczby istniejących stron indeksowych do 524 (przerywanie P > 524
) powoduje pełne rejestrowanie . Moglibyśmy również wprowadzić zmiany takie, że R
wynosi nie mniej niż 8, aby uzyskać pełne logowanie . Na przykład ustawienie P = 1000
i I = 125
daje R = 8
, z następującymi wynikami:
125 wstawionych wierszy zostało w pełni zalogowanych zgodnie z oczekiwaniami. (Nie jest to spowodowane pełnym logowaniem pierwszej strony, ponieważ indeks nie był wcześniej pusty).
Stosunek stron dla indeksów partycjonowanych
Jeśli wszystkie poprzednie testy zakończą się niepowodzeniem, jeden pozostały test wymaga R >= 8
i może tylko być spełnione, gdy liczba partycji (T
) jest większe niż 1 i jest ponad 250 szacowanych wstawione wiersze (I
). Przypomnij:
- Jeśli
R >= 8
:- Jeśli
T > 1
iI > 250
zwróć prawda , w przeciwnym razie fałsz .
- Jeśli
Jedna subtelność:dla partycjonowanych indeksów, reguła, która mówi, że wszystkie wiersze na pierwszej stronie są w pełni rejestrowane (dla początkowo pustego indeksu) ma zastosowanie na partycję . W przypadku obiektu z 15 000 partycjami oznacza to 15 000 w pełni zalogowanych „pierwszych” stron.
Podsumowanie i końcowe przemyślenia
Formuły i kolejność oceny opisane w treści bazują na kontroli kodu za pomocą debuggera. Zostały one przedstawione w formie, która ściśle odzwierciedla czas i kolejność użyte w prawdziwym kodzie.
Można nieco zmienić kolejność i uprościć te warunki, aby uzyskać bardziej zwięzłe podsumowanie praktycznych wymagań dotyczących minimalnego rejestrowania podczas wstawiania do b-drzewa za pomocą INSERT...SELECT
. Poniższe udoskonalone wyrażenia wykorzystują następujące trzy parametry:
P
=liczba istniejących indeksuj strony na poziomie liścia.I
=szacowany liczba wierszy do wstawienia.S
=szacowany wstaw rozmiar danych na stronach 8KB.
Zbiorcze ładowanie zestawu wierszy
- Używa
sqlmin!RowsetBulk
. - Wymaga pustego klastrowany cel indeksu z
TABLOCK
(lub odpowiednik). - Wymaga
DMLRequestSort = true
na wstawce z indeksem klastrowym operator. DMLRequestSort
jest ustawiona natrue
jeśliI > 250
iS > 2
.- Wszystkie wstawione wiersze są minimalnie rejestrowane .
Sch-M
blokada uniemożliwia równoczesny dostęp do tabeli.
Kontekst szybkiego ładowania
- Używa
sqlmin!FastLoadContext
. - Włącza minimalnie rejestrowane wstawia do indeksów b-drzewa:
- Sklastrowane lub nieklastrowe.
- Z blokadą stołu lub bez.
- Indeks docelowy jest pusty lub nie.
- Wymaga
DMLRequestSort = true
na powiązanej wstawce indeksu operator planu. - Tylko wiersze zapisywane na nowych stronach są ładowane zbiorczo i minimalnie rejestrowane .
- Pierwsza strona poprzednio pustego indeksu partycja jest zawsze w pełni zalogowana .
- Absolutne minimum
I >= 100
. - Wymaga flagi śledzenia 610 przed SQL Server 2016.
- Domyślnie dostępne od SQL Server 2016 (flaga śledzenia 692 wyłącza).
DMLRequestSort
jest ustawiona na true
dla:
- Dowolny indeks (partycjonowane lub nie), jeśli:
I > 250
iP < 3
iS > 2
; lubI >= 100
iP > 524
iP < I * 8
Dla tylko indeksów partycjonowanych (z> 1 partycją), DMLRequestSort
jest również ustawiona na true
jeśli:
I > 250
iP > 16
iP >= I * 8
Istnieje kilka interesujących przypadków wynikających z tych FastLoadContext
warunki:
- Wszystkie wstawia do niepartycjonowanego indeks z od 3 do 524 (włącznie) istniejące strony liści będą w pełni rejestrowane niezależnie od liczby i całkowitego rozmiaru dodanych wierszy. Najbardziej zauważalnie wpłynie to na duże wstawki do małych (ale nie pustych) tabel.
- Wszystkie wstawia do partycjonowanej indeks z od 3 do 16 istniejące strony będą w pełni rejestrowane .
- Duże wstawki za duże bez partycji indeksy nie mogą być minimalnie rejestrowane z powodu nierówności
P < I * 8
. KiedyP
jest duży, odpowiednio duży szacowany liczba wstawionych wierszy (I
) jest wymagane. Na przykład indeks z 8 milionami stron nie obsługuje minimalnego rejestrowania podczas wstawiania 1 miliona wierszy lub mniej.
Indeksy nieklastrowane
Te same uwagi i obliczenia, które zastosowano do indeksów klastrowych w prezentacjach, dotyczą nieklastrowanych indeksy b-drzewa, o ile indeks jest utrzymywany przez dedykowanego operatora planu (szeroki lub na indeks plan). Indeksy nieklastrowane obsługiwane przez podstawowy operator tabeli (np. Wstawka indeksu klastrowego ) nie kwalifikują się do FastLoadContext
.
Pamiętaj, że parametry formuły muszą być oceniane od nowa dla każdego nieklastrowanego operator indeksu — obliczony rozmiar wiersza, liczba istniejących stron indeksu i oszacowanie liczności.
Uwagi ogólne
Uważaj na szacunki o niskiej kardynalności przy wstawce indeksu operatora, ponieważ wpłyną one na I
i S
parametry. Jeśli próg nie zostanie osiągnięty z powodu błędu oszacowania liczności, wstawka zostanie w pełni zarejestrowana .
Pamiętaj, że DMLRequestSort
jest buforowany z planem — nie jest oceniany przy każdym wykonaniu ponownie wykorzystanego planu. Może to wprowadzić formę dobrze znanego problemu z wrażliwością parametrów (znanego również jako „podsłuchiwanie parametrów”).
Wartość P
(indeksowe strony liści) nie jest odświeżany na początku każdego oświadczenia. Obecna implementacja buforuje wartość dla całej partii . Może to mieć nieoczekiwane skutki uboczne. Na przykład TRUNCATE TABLE
w tej samej partii jako INSERT...SELECT
nie zresetuje P
do zera dla obliczeń opisanych w tym artykule — będą nadal używać wartości sprzed przycięcia, a ponowna kompilacja nie pomoże. Rozwiązaniem jest przesyłanie dużych zmian w oddzielnych partiach.
Flagi śledzenia
Możliwe jest wymuszenie FDemandRowsSortedForPerformance
aby zwrócić prawdę ustawiając nieudokumentowane i nieobsługiwane trace flag 2332, jak pisałem w Optymalizacji zapytań T-SQL, które zmieniają dane. Gdy TF 2332 jest aktywny, szacunkowa liczba wierszy do wstawienia nadal musi wynosić co najmniej 100 . TF 2332 wpływa na minimalne logowanie decyzja dla FastLoadContext
tylko (działa to dla stosów partycjonowanych do DMLRequestSort
dotyczy, ale nie ma wpływu na sam stos, ponieważ FastLoadContext
dotyczy tylko indeksów).
szeroki/na indeks kształt planu dla konserwacji indeksu nieklastrowanego może być wymuszony dla tabel magazynu wierszy przy użyciu flagi śledzenia 8790 (nie jest to oficjalnie udokumentowane, ale wspomniane w artykule z bazy wiedzy Knowledge Base, a także w moim artykule jako link do TF2332 tuż powyżej).
Powiązane czytanie
Wszystko autorstwa Sunila Agarwala z zespołu SQL Server:
- Co to są optymalizacje importu zbiorczego?
- Optymalizacja importu zbiorczego (minimalne rejestrowanie)
- Minimalne zmiany rejestrowania w SQL Server 2008
- Minimalne zmiany rejestrowania w SQL Server 2008 (część 2)
- Minimalne zmiany rejestrowania w SQL Server 2008 (część 3)