Mamy proces, który generuje raport asortymentowy. Po stronie klienta proces dzieli konfigurowalną liczbę wątków roboczych, aby utworzyć fragment danych dla raportu, który odpowiada jednemu z wielu sklepów (potencjalnie tysiące, zwykle dziesiątki). Każdy wątek roboczy wywołuje usługę sieci Web, która wykonuje procedurę przechowywaną.
Proces bazy danych do przetwarzania każdego fragmentu gromadzi wiązkę danych do tabeli #Temporary. Na końcu każdej porcji przetwarzania dane są zapisywane w stałej tabeli w tempdb. Wreszcie na koniec procesu jeden wątek po stronie klienta żąda wszystkich danych ze stałej tabeli tempdb.
Im więcej użytkowników uruchamia ten raport, tym wolniej się robi. Analizowałem aktywność w bazie danych. W pewnym momencie widziałem 35 oddzielnych wniosków zablokowanych w jednym punkcie procesu. Wszystkie te identyfikatory SPID miały czas oczekiwania rzędu 50 ms LATCH_EX
na zasób METADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)
. Jeden SPID ma ten zasób, a wszystkie inne blokują. Nie znalazłem nic na temat tego zasobu oczekiwania podczas wyszukiwania w sieci.
Tabela w tempdb, której używamy, ma IDENTITY(1,1)
kolumnę. Czy te identyfikatory SPID czekają na kolumnę TOŻSAMOŚĆ? Jakie metody moglibyśmy zastosować w celu zmniejszenia lub wyeliminowania blokowania?
Serwer jest częścią klastra. Na serwerze działa 64-bitowy program SQL Server 2012 Standard Edition SP1 w 64-bitowym systemie Windows 2008 R2 Enterprise. Serwer ma 64 GB pamięci RAM i 48 procesorów, ale baza danych może używać tylko 16, ponieważ jest to edycja standardowa.
(Pamiętaj, że nie jestem podekscytowany projektem użycia stałej tabeli w tempdb do przechowywania wszystkich tych danych. Zmiana tego byłaby interesującym wyzwaniem technicznym i politycznym, ale jestem otwarta na sugestie).
AKTUALIZACJA 23.03.2013
Otworzyliśmy skrzynkę pomocy technicznej w firmie Microsoft. Będę aktualizować to pytanie, gdy będziemy dowiedzieć się więcej.
AKTUALIZACJA 5/10/2013
Inżynier wsparcia SQL Server zgodził się, że oczekiwania zostały spowodowane przez kolumnę TOŻSAMOŚĆ. Usunięcie TOŻSAMOŚCI wyeliminowało oczekiwania. Nie mogliśmy powielić problemu na SQL 2008 R2; miało to miejsce tylko w SQL 2012.
źródło
Odpowiedzi:
Zakładając, że możesz wyizolować problem z generowaniem wartości tożsamości (spróbuj usunąć tę kolumnę jako test), zaleciłbym to:
IDENTITY
właściwość z kolumny w końcowej tabeli.Więc jeśli masz identyfikatory sklepu 3 i 4, uzyskasz końcowe wartości identyfikatora takie jak to:
Lub coś podobnego do tego. Masz pomysł.
Wyeliminuje to potrzebę serializacji przy
IDENTITY
generowaniu, jednocześnie zachowując wyjątkowość w końcowym wyniku.Alternatywnie, w zależności od tego, jak działa proces, wstaw końcowe obliczone wartości id do tabel #Temporary. Następnie możesz utworzyć widok, który
UNION ALL
jest nimi razem, eliminując w ogóle potrzebę kopiowania danych.źródło
IDENTITY
kolumna. Usunęliśmy go z już szerokiego indeksu klastrowego i całkowicie usunęliśmy kolumnę. To nie było konieczne. Następnie te LATCH_EX oczekiwania zniknęły. Nie mogliśmy powielić oczekiwań na SQL 2008 R2. Problem pojawił się tylko na SQL Server 2012.IDENTITY
wartości, został przepisany w celu użycia nowej funkcji generowania sekwencji, która była nowa w 2012 roku. W <2012 roku możesz zobaczyć inny typ zatrzasku, chociaż jeśli nie było problemu z perf, to wydaje się, że był regresja w kodzie. W każdym razie usunięcieIDENTITY
kolumny jest najbezpieczniejsze.(Zaktualizowano w lutym 2019 r.)
To jest stary post, który powiedział, że w końcu udało mi się przekonać Microsoft, że sam fakt, który to się dzieje, jest rzeczywiście wadą.
Aktualizacja: MS potwierdziło błąd i przypisało mu błąd nr 12628722.
Widziałem ten post w listopadzie 2018 r., Kiedy zaczęliśmy odczuwać podobne skutki po aktualizacji z Sql Server 2005 do Sql Server 2017. Tabela o wielkości 3,3 miliona wierszy, która zwykła zajmować 10 sekund, zaczęła nagle przyjmować 10 minuty na tabelach z
Identity
kolumnami.Okazuje się, że kryją się za tym dwa problemy:
Zajęło mi to 4 tygodnie, ale zaraz po wakacjach dostałem spóźniony prezent od Świętego Mikołaja - potwierdzenie, że problem był rzeczywiście wadą.
Znaleźliśmy kilka możliwych obejść, dopóki nie zostanie to naprawione:
Option (MaxDop 1)
w zapytaniu, aby przekształcić wstawkę zbiorczą z powrotem w plan szeregowy.Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn
)SELECT...INTO
Aktualizacja: Poprawka, którą MS wdroży, polega na przywróceniu tego rodzaju wkładek z powrotem do korzystania z
Serialized
planu. Jest to planowane dla Sql Server 2017 CU14 (brak wiadomości o innych wersjach Sql Server - przepraszam!). Po wdrożeniu flaga śledzenia 9492 będzie musiała zostać włączona na poziomie serwera lub za pośrednictwemDBCC TraceOn
.źródło