Mam zapytanie, które działa na naszym serwerze około 3 godzin - i nie korzysta z przetwarzania równoległego. (około 1,15 miliona rekordów dbo.Deidentified
, 300 rekordów w dbo.NamesMultiWord
). Serwer ma dostęp do 8 rdzeni.
UPDATE dbo.Deidentified
WITH (TABLOCK)
SET IndexedXml = dbo.ReplaceMultiWord(IndexedXml),
DE461 = dbo.ReplaceMultiWord(DE461),
DE87 = dbo.ReplaceMultiWord(DE87),
DE15 = dbo.ReplaceMultiWord(DE15)
WHERE InProcess = 1;
i ReplaceMultiword
jest procedurą zdefiniowaną jako:
SELECT @body = REPLACE(@body,Names,Replacement)
FROM dbo.NamesMultiWord
ORDER BY [WordLength] DESC
RETURN @body --NVARCHAR(MAX)
Czy wezwanie do ReplaceMultiword
zapobiegania tworzeniu równoległego planu? Czy istnieje sposób na przepisanie tego w celu umożliwienia równoległości?
ReplaceMultiword
działa w kolejności malejącej, ponieważ niektóre zamienniki są krótkimi wersjami innych i chcę, aby jak najdłuższe dopasowanie zakończyło się powodzeniem.
Na przykład może istnieć „George Washington University” i inny z „Washington University”. Gdyby mecz „Washington University” był pierwszy, to „George” zostałby w tyle.
Technicznie mogę korzystać z CLR, po prostu nie wiem, jak to zrobić.
SELECT @var = REPLACE ... ORDER BY
Budowa nie jest gwarantowane do pracy, jak można się spodziewać. Przykładowy element Connect (patrz odpowiedź Microsoft). Zatem przejście na SQLCLR ma tę dodatkową zaletę, że gwarantuje prawidłowe wyniki, co zawsze jest miłe.Odpowiedzi:
UDF zapobiega równoległości. To także powoduje, że ta szpula jest.
Możesz użyć CLR i skompilowanego wyrażenia regularnego do wyszukiwania i zamiany. Nie blokuje równoległości, dopóki obecne są wymagane atrybuty, i prawdopodobnie będzie znacznie szybsze niż wykonywanie 300
REPLACE
operacji TSQL na wywołanie funkcji.Przykładowy kod znajduje się poniżej.
Zależy to od istnienia CLR UDF, jak poniżej (
DataAccessKind.None
powinno to oznaczać, że szpula znika, a także jest dostępna do ochrony na Halloween i nie jest potrzebna, ponieważ nie ma dostępu do tabeli docelowej).źródło
where
klauzuli za pomocą testu dopasowania do wyrażenia regularnego, ponieważ większość zapisów jest niepotrzebna - gęstość trafień powinna być niska, ale moje umiejętności w C # (jestem facetem w C ++) nie zabierz mnie tam. Myślałem zgodnie z procedurą,public static SqlBoolean CanReplaceMultiWord(SqlString inputString, SqlXml replacementSpec)
która by zwróciła,return Regex.IsMatch(inputString.ToString());
ale otrzymuję błędy w tej instrukcji return, takie jak `System.Text.RegularExpressions.Regex jest typem, ale jest używany jak zmienna.Konkluzja : Dodanie kryteriów do
WHERE
klauzuli i podzielenie zapytania na cztery osobne zapytania, po jednym dla każdego pola, pozwoliło serwerowi SQL na zapewnienie równoległego planu i spowodowało, że zapytanie uruchomiono 4 razy szybciej niż bez dodatkowego testu wWHERE
klauzuli. Podział zapytań na cztery bez testu tego nie zrobił. Nie dodano też testu bez dzielenia zapytań. Optymalizacja testu skróciła całkowity czas pracy do 3 minut (z pierwotnych 3 godzin).Moja oryginalna funkcja UDF zajęła 3 godziny 16 minut na przetworzenie 1 177 731 wierszy i przetestowanie 1,216 GB danych nvarchar. Korzystając z CLR dostarczonego przez Martina Smitha w swojej odpowiedzi, plan wykonania wciąż nie był równoległy, a zadanie trwało 3 godziny i 5 minut.
Po zapoznaniu się z tymi
WHERE
kryteriami może pomóc w doprowadzeniuUPDATE
do równoległości, zrobiłem następujące. Dodałem funkcję do modułu CLR, aby sprawdzić, czy pole ma dopasowanie do wyrażenia regularnego:i, w
internal class ReplaceSpecification
, dodałem kod, aby wykonać test względem wyrażenia regularnegoJeśli wszystkie pola są testowane w jednej instrukcji, serwer SQL nie wykonuje pracy równoległej
Czas na wykonanie ponad 4 1/2 godziny i nadal działa. Plan wykonania:
Jeśli jednak pola zostaną podzielone na osobne instrukcje, zostanie użyty równoległy plan pracy, a moje użycie procesora wzrośnie z 12% w przypadku planów szeregowych do 100% w przypadku planów równoległych (8 rdzeni).
Czas na wykonanie 46 minut. Statystyki wierszy wykazały, że około 0,5% rekordów zawierało co najmniej jedno dopasowanie wyrażenia regularnego. Plan wykonania:
Teraz głównym problemem na czasie była
WHERE
klauzula. Następnie zastąpiłem test wyrażenia regularnego wWHERE
klauzuli algorytmem Aho-Corasick zaimplementowanym jako CLR. Skróciło to całkowity czas do 3 minut 6 sekund.Wymagało to następujących zmian. Załaduj zespół i funkcje dla algorytmu Aho-Corasick. Zmień
WHERE
klauzulę naI dodaj następujące przed pierwszym
UPDATE
źródło