Database
 sql >> Baza danych >  >> RDS >> Database

Jak uruchamiają się plany równoległe – część 1

Ta pięcioczęściowa seria szczegółowo opisuje sposób uruchamiania planów równoległych w trybie wiersza programu SQL Server. Ta pierwsza część obejmuje rolę nadrzędnego zadania (koordynatora) w przygotowaniu planu do równoległej realizacji. Obejmuje inicjowanie każdego operatora i dodawanie ukrytych profili do zbierania danych o wydajności środowiska wykonawczego, takich jak rzeczywista liczba wierszy i czas, który upłynął.

Konfiguracja

Aby zapewnić konkretną podstawę do analizy, prześledzimy, w jaki sposób rozpoczyna się wykonywanie konkretnego zapytania równoległego. Korzystałem z publicznego Stack Overflow 2013 baza danych (pobierz szczegóły). Pożądany kształt planu można również uzyskać na podstawie mniejszego zestawu danych Stack Overflow 2010, jeśli jest to wygodniejsze. Można go pobrać pod tym samym linkiem. Dodałem jeden indeks nieklastrowany:

CREATE NONCLUSTERED INDEX PP
ON dbo.Posts
(
    PostTypeId ASC,
    CreationDate ASC
);

Moje środowisko testowe to SQL Server 2019 CU9 na laptopie z 8 rdzeniami i 16 GB pamięci przydzielonej do instancji. Poziom zgodności 150 jest używany wyłącznie. Wspominam o tych szczegółach, aby pomóc ci odtworzyć plan docelowy, jeśli chcesz. Podstawy wykonywania równoległego w trybie wiersza nie zmieniły się od SQL Server 2005, więc poniższa dyskusja ma szerokie zastosowanie.

Zapytanie testowe zwraca całkowitą liczbę pytań i odpowiedzi pogrupowanych według miesiąca i roku:

WITH 
    MonthlyPosts AS 
    (
        SELECT 
            P.PostTypeId, 
            CA.TheYear, 
            CA.TheMonth, 
            Latest = MAX(P.CreationDate)
        FROM dbo.Posts AS P
        CROSS APPLY 
        (
            VALUES
            (
                YEAR(P.CreationDate), 
                MONTH(P.CreationDate)
            )
        ) AS CA (TheYear, TheMonth)
        GROUP BY 
            P.PostTypeId, 
            CA.TheYear, 
            CA.TheMonth
    )
SELECT 
    rn = ROW_NUMBER() OVER (
        ORDER BY Q.TheYear, Q.TheMonth),
    Q.TheYear, 
    Q.TheMonth, 
    LatestQuestion = Q.Latest,
    LatestAnswer = A.Latest
FROM MonthlyPosts AS Q
JOIN MonthlyPosts AS A
    ON A.TheYear = Q.TheYear
    AND A.TheMonth = Q.TheMonth
WHERE 
    Q.PostTypeId = 1
    AND A.PostTypeId = 2
ORDER BY 
    Q.TheYear,
    Q.TheMonth
OPTION 
(
    USE HINT ('DISALLOW_BATCH_MODE'),
    USE HINT ('FORCE_DEFAULT_CARDINALITY_ESTIMATION'),
    ORDER GROUP,
    MAXDOP 2
);

Użyłem wskazówek, aby uzyskać konkretny plan trybu wiersza kształtu. Wykonanie jest ograniczone do DOP 2, aby niektóre szczegóły pokazane później były bardziej zwięzłe.

Szacunkowy plan wykonania to (kliknij, aby powiększyć):

Tło

Optymalizator zapytań tworzy pojedynczy skompilowany plan dla partii. Każda instrukcja w partii jest oznaczona do wykonania seryjnego lub równoległego, w zależności od kwalifikowalności i szacowanych kosztów.

Plan równoległy zawiera giełdy (operatory równoległości). Giełdy mogą pojawiać się w rozpowszechnianiu strumieni , podział strumieni lub zbierz strumienie Formularz. Każdy z tych typów wymiany wykorzystuje te same podstawowe komponenty, po prostu inaczej połączone, z różną liczbą wejść i wyjść. Aby uzyskać więcej informacji na temat wykonywania równoległego w trybie wiersza, zobacz Plany wykonywania równoległego – gałęzie i wątki.

Zdegraduj DOP

Stopień równoległości (DOP) dla planu równoległego można w razie potrzeby obniżyć w czasie wykonywania. Równoległe zapytanie może rozpocząć się od żądania DOP 8, ale będzie stopniowo obniżane do DOP 4, DOP 2 i wreszcie DOP 1 z powodu braku zasobów systemowych w tym momencie. Jeśli chcesz zobaczyć to w akcji, obejrzyj ten krótki film autorstwa Erika Darlinga.

Uruchomienie planu równoległego w jednym wątku może się również zdarzyć, gdy buforowany plan równoległy jest ponownie używany przez sesję ograniczoną do DOP 1 przez ustawienie środowiskowe (np. maskę koligacji lub zarządcę zasobów). Zobacz Mit:SQL Server buforuje plan szeregowy z każdym planem równoległym, aby uzyskać szczegółowe informacje.

Bez względu na przyczynę, obniżenie poziomu DOP buforowanego planu równoległego nie skutkować opracowaniem nowego planu seryjnego. SQL Server ponownie wykorzystuje istniejący plan równoległy, wyłączając wymiany. Rezultatem jest plan „równoległy”, który jest wykonywany w jednym wątku. Wymiany nadal pojawiają się w planie, ale są pomijane w czasie wykonywania.

SQL Server nie może promować planu szeregowego do wykonywania równoległego przez dodanie wymian w czasie wykonywania. To wymagałoby nowej kompilacji.

Inicjowanie planu równoległego

Plan równoległy zawiera wszystkie wymiany potrzebne do wykorzystania dodatkowych wątków roboczych, ale jest dodatkowe prace konfiguracyjne potrzebne w czasie wykonywania przed rozpoczęciem wykonywania równoległego. Jednym z oczywistych przykładów jest to, że dodatkowe wątki robocze muszą być przydzielone do określonych zadań w ramach planu, ale jest o wiele więcej.

Zacznę od punktu, w którym równoległy plan został pobrany z pamięci podręcznej planów. W tym momencie istnieje tylko oryginalny wątek przetwarzający bieżące żądanie. Ten wątek jest czasami nazywany „wątkiem koordynatora” w planach równoległych, ale wolę terminy „zadanie nadrzędne ” lub „pracownik-rodzic”. Poza tym nie ma nic specjalnego w tym wątku; jest to ten sam wątek, którego używa połączenie do przetwarzania żądań klientów i uruchamiania planów szeregowych do końca.

Aby podkreślić, że istnieje tylko jeden wątek w tej chwili chcę, abyś zwizualizował plan w tym momencie w ten sposób:

W tym poście będę używał zrzutów ekranu z Sentry One Plan Explorer, ale tylko dla tego pierwszego widoku pokażę również wersję SSMS:

W obu reprezentacjach kluczową różnicą jest brak ikon równoległości na każdym operatorze, mimo że wymiany są nadal obecne. W tej chwili istnieje tylko zadanie nadrzędne, działające w oryginalnym wątku połączenia. Brak dodatkowych wątków roboczych zostały zarezerwowane, utworzone lub przypisane do zadań. Miej na uwadze powyższą reprezentację planu w miarę postępów.

Tworzenie planu wykonywalnego

Plan w tym momencie to w zasadzie tylko szablon które mogą być wykorzystane jako podstawa do przyszłej realizacji. Aby przygotować go do konkretnego uruchomienia, SQL Server musi wprowadzić wartości środowiska wykonawczego, takie jak bieżący użytkownik, kontekst transakcji, wartości parametrów, identyfikatory dowolnych obiektów utworzonych w czasie wykonywania (np. tabele tymczasowe i zmienne) i tak dalej.

W przypadku planu równoległego SQL Server musi wykonać sporo dodatkowej pracy przygotowawczej, aby doprowadzić wewnętrzną maszynerię do punktu, w którym można rozpocząć wykonywanie. Wątek roboczy nadrzędnego zadania jest odpowiedzialny za wykonanie prawie całej tej pracy (i na pewno całej pracy, którą omówimy w części 1).

Proces przekształcania szablonu planu dla konkretnego przebiegu jest znany jako tworzenie planu wykonywalnego . Czasami trudno jest zachować prostą terminologię, ponieważ terminy są często przeładowane i niewłaściwie stosowane (nawet przez Microsoft), ale dołożę wszelkich starań, aby zachować jak największą spójność.

Konteksty wykonania

Możesz pomyśleć o kontekście wykonania jako szablon planu wypełniony wszystkimi szczegółowymi informacjami dotyczącymi środowiska uruchomieniowego wymaganymi przez konkretny wątek. Plan wykonywalny dla serii Instrukcja składa się z pojedynczego kontekstu wykonania, w którym pojedynczy wątek uruchamia cały plan.

równoległy wykonywalny plan zawiera zbiór kontekstów wykonania :jeden dla zadania nadrzędnego i jeden na wątek w każdej gałęzi równoległej. Każdy dodatkowy równoległy wątek roboczy uruchamia swoją część ogólnego planu we własnym kontekście wykonania. Na przykład plan równoległy z trzema gałęziami działającymi w DOP 8 ma (1 + (3 * 8)) =25 kontekstów wykonania. Konteksty wykonywania szeregowego są buforowane do ponownego użycia, ale dodatkowe konteksty wykonywania równoległego nie są.

Zadanie nadrzędne zawsze istnieje przed wszelkimi dodatkowymi zadaniami równoległymi, więc jest mu przypisywany kontekst wykonania zero . Konteksty wykonywania używane przez pracowników równoległych zostaną utworzone później, po pełnym zainicjowaniu kontekstu nadrzędnego. Dodatkowe konteksty są sklonowane z kontekstu nadrzędnego, a następnie dostosowane do konkretnego zadania (jest to omówione w części 2).

Istnieje szereg działań związanych z uruchomieniem zerowego kontekstu wykonania. Próba wymienienia ich wszystkich jest niepraktyczna, ale przydatne będzie omówienie niektórych z głównych, które mają zastosowanie do naszego zapytania testowego. Nadal będzie ich zbyt wiele na jedną listę, więc podzielę je na (nieco arbitralnie) sekcje:

1. Inicjalizacja kontekstu nadrzędnego

Kiedy przesyłamy instrukcję do wykonania, kontekst nadrzędnego zadania (zerowy kontekst wykonania) jest inicjowany za pomocą:

  • Odniesienie do podstawowej transakcji (jawne, niejawne lub automatyczne). Pracownicy równolegli będą uruchamiać transakcje podrzędne, ale wszystkie są objęte zakresem transakcji podstawowej.
  • Lista instrukcji parametrów i ich aktualne wartości.
  • Podstawowy obiekt pamięci (PMO) używany do zarządzania przydziałami i przydziałami pamięci.
  • mapa połączona operatorów (węzłów zapytań) w planie wykonywalnym.
  • Fabryka dla każdego wymaganego dużego obiektu (kropelka) uchwyty.
  • Klasy blokad do śledzenia wielu blokad utrzymywanych przez pewien czas podczas wykonywania. Nie wszystkie plany wymagają klas blokady ponieważ operatorzy w pełni strumieniowego zazwyczaj blokują i odblokowują poszczególne wiersze po kolei.
  • Szacowany przyznanie pamięci dla zapytania.
  • Pamięć w trybie wiersza udziela opinii struktury dla każdego operatora (SQL Server 2019).

Wiele z tych rzeczy będzie później używanych lub odwoływanych przez zadania równoległe, więc najpierw muszą istnieć w zakresie nadrzędnym.

2. Metadane kontekstu nadrzędnego

Kolejne główne wykonywane zadania to:

  • Sprawdzanie szacowanego kosztu zapytania mieści się w limicie określonym przez opcje konfiguracji limitu kosztów zarządcy zapytań.
  • Aktualizowanie używania indeksu rekordy – ujawnione przez sys.dm_db_index_usage_stats .
  • Tworzenie buforowanych wartości wyrażeń (stałe uruchomieniowe).
  • Tworzenie listy operatorów profilowania służy do zbierania metryk środowiska uruchomieniowego, takich jak liczba wierszy i czasy, jeśli zażądano tego w bieżącym wykonaniu. Same profilery nie zostały jeszcze utworzone, tylko lista.
  • Wykonywanie zrzutu czeka dla sesji czeka funkcja ujawniona przez sys.dm_exec_session_wait_stats .

3. DOP i przyznanie pamięci

Nadrzędny kontekst zadania teraz:

  • Oblicza stopień równoległości w czasie wykonywania (DOP ). Wpływa na to liczba bezpłatnych procesów roboczych (patrz wcześniej „Zmiana DOP na starszą wersję”), gdzie można je umieścić między węzłami, oraz liczba flag śledzenia.
  • Rezerwuje wymaganą liczbę wątków. Ten krok to czysta księgowość – same wątki mogą w tym momencie nie istnieć. SQL Server śledzi maksymalną dozwoloną liczbę wątków. Rezerwowanie wątków odejmuje od tej liczby. Po zakończeniu wątków maksymalna liczba zostaje ponownie zwiększona.
  • Ustawia limit czasu przyznawania pamięci .
  • Oblicza przydział pamięci, w tym pamięć wymaganą do buforów wymiany.
  • Uzyskuje przyznanie pamięci za pośrednictwem odpowiedniego semafora zasobów .
  • Tworzy obiekt menedżera do obsługi równoległych podprocesów . Zadanie nadrzędne to proces najwyższego poziomu; dodatkowe zadania są również nazywane podprocesami .

Chociaż w tym momencie wątki są „zarezerwowane”, SQL Server może nadal napotkać THREADPOOL czeka później, gdy próbuje użyć jednego z „zarezerwowanych” wątków. Rezerwacja gwarantuje, że SQL Server pozostanie w pobliżu skonfigurowanej maksymalnej liczby wątków przez cały czas, ale wątek fizyczny może nie być natychmiast dostępny z puli wątków . Kiedy tak się stanie, nowy wątek będzie musiał zostać uruchomiony przez system operacyjny, co może chwilę potrwać. Więcej informacji na ten temat można znaleźć w artykule Unusual THREADPOOL Waits autorstwa Josha Darnella.

4. Zapytanie o konfigurację skanowania

Plany w trybie wiersza są wykonywane iteracyjnie moda, zaczynając od nasady. Plan, który mamy w tej chwili nie jest jeszcze zdolny do tego trybu realizacji. Wciąż jest to w dużej mierze szablon, nawet jeśli zawiera już sporą ilość informacji dotyczących wykonania.

SQL Server musi przekonwertować bieżącą strukturę na drzewo iteratorów , każda z metodami takimi jak Open , GetRow i Close . Metody iteratorów są połączone z ich dziećmi za pomocą wskaźników do funkcji. Na przykład wywołanie GetRow na katalogu głównym rekursywnie wywołuje GetRow na operatorach potomnych, aż osiągnie się poziom liścia i rząd zacznie „bulgotać” na drzewie. Aby odświeżyć szczegóły, zobacz Iteratory, plany zapytań i dlaczego działają wstecz.

Koniec części 1

Poczyniliśmy duże postępy w tworzeniu kontekstu wykonania zadania nadrzędnego. W części 2 będziemy śledzić, jak SQL Server konstruuje drzewo skanowania zapytań niezbędne do iteracyjnego wykonania.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rozwiązania wyzwań generatora serii liczb – Część 4

  2. Tap and Park:model danych aplikacji parkingowej

  3. Zarządzanie bezpieczeństwem danych

  4. Czym jest kursor w SQL i jak go zaimplementować?

  5. Nieoczekiwany efekt uboczny dodania filtrowanego indeksu