PL EN
Pobierz CV
← Wszystkie publikacje
Bazy danych Badanie · Artykuł Artur Łaski

Techniki optymalizacji Microsoft SQL Server 2022 — kompleksowa analiza naukowa

11 min czytania Artur Łaski Read in English
SQL

Analiza naukowa optymalizacji wydajności Microsoft SQL Server 2022: modele kosztu zapytań, Intelligent Query Processing, indeksy, TempDB, pamięć, storage i monitoring — z gotowymi eksperymentami T-SQL.

Streszczenie

Microsoft SQL Server 2022 wprowadza szereg usprawnień technologicznych: lepszą optymalizację zapytań, zarządzanie pamięcią, indeksowanie, inteligentne przetwarzanie zapytań, In-Memory OLTP oraz funkcje chmury hybrydowej. Organizacje generują coraz większe wolumeny danych, dlatego optymalizacja systemów bazodanowych pozostaje kluczowym warunkiem wysokiej wydajności, skalowalności i niezawodności — zarówno w środowiskach transakcyjnych, jak i analitycznych.

Artykuł przedstawia naukową analizę optymalizacji wydajności w SQL Server 2022, łącząc podstawy teoretyczne, praktyczne metody strojenia i dobre praktyki architektoniczne. Zawiera modele matematyczne szacowania kosztu zapytań, alokacji pamięci i rozkładu danych, a także tabele z metrykami optymalizacji, porównaniem wyników i rekomendowanymi strategiami indeksowania. Wyniki pokazują kluczową rolę Intelligent Query Processing (IQP), Parameter Sensitive Plan Optimization, strojenia TempDB, indeksów kolumnowych i zarządzania buforem.

1. Wprowadzenie

Szybki rozwój korporacyjnych systemów informatycznych i wykładniczy wzrost ilości danych stawiają przed silnikami relacyjnych baz danych coraz większe wymagania. SQL Server 2022 — najnowsza główna wersja flagowego systemu RDBMS Microsoftu — oferuje zaawansowaną optymalizację zapytań, adaptacyjne dostosowywanie planów, rozbudowane modele optymalizacji pamięci i storage’u oraz lepszą integrację z chmurą.

Optymalizacja wydajności nie ogranicza się już do ręcznego zakładania indeksów i przepisywania zapytań. Obejmuje inteligentne funkcje silnika, głębokie strojenie architektury i adaptacyjne zachowanie w trakcie wykonania. Artykuł łączy modele teoretyczne z praktycznymi technikami stosowanymi w wysoko obciążonych systemach transakcyjnych (OLTP), środowiskach analitycznych (OLAP) i architekturach hybrydowych.

2. Podstawy teoretyczne

Optymalizacja w SQL Server opiera się na trzech filarach:

  1. Optymalizacja zapytań i plany wykonania
  2. Zarządzanie pamięcią i storage’em
  3. Indeksowanie i modelowanie danych

SQL Server 2022 korzysta z optymalizatora kosztowego. Szuka planu zapytania o najniższym szacowanym koszcie:

Cost(Q) = Σ Cᵢ   (i = 1 … n)

Q  — zapytanie
Cᵢ — szacowany koszt pojedynczego operatora (scan, seek, sort, join, agregacja)

Dokładniejszy model dla operacji ograniczonych przez I/O:

C_IO = α · P_read + β · P_write

P_read  — liczba odczytów logicznych
P_write — liczba zapisów
α, β    — wagi odzwierciedlające opóźnienia urządzeń

SQL Server 2022 rozszerza te modele o mechanizmy adaptacyjne w ramach Intelligent Query Processing.

3. Intelligent Query Processing (IQP) w SQL Server 2022

3.1 Tryb wsadowy (batch mode) na rowstore

Wykonanie wsadowe, pierwotnie zarezerwowane dla indeksów kolumnowych, obsługuje teraz także operacje na rowstore: agregacje, funkcje okna, sortowania i złączenia. Tryb wsadowy znacząco zmniejsza zużycie CPU dzięki przetwarzaniu wektorowemu.

3.2 Przybliżone przetwarzanie zapytań

W dużych zapytaniach analitycznych funkcje przybliżone, takie jak APPROX_COUNT_DISTINCT czy przybliżone percentyle, skracają czas wykonania z minut do sekund przy zachowaniu akceptowalnej dokładności statystycznej.

3.3 Parameter Sensitive Plan Optimization (PSPO)

SQL Server może generować wiele planów wykonania dla różnych rozkładów wartości parametru. Dla parametru P o rozkładzie danych D(P) silnik utrzymuje:

{ Plan₁ (P ∈ D₁), Plan₂ (P ∈ D₂), …, Planₖ (P ∈ Dₖ) }

Ta funkcja rozwiązuje znany od lat problem parameter sniffing, gdy jeden zapisany w pamięci plan działa dobrze dla części wartości parametru, a źle dla pozostałych.

4. Modelowanie danych i optymalizacja schematu

Poprawny projekt schematu pozostaje fundamentem wydajności.

4.1 Normalizacja a denormalizacja

Normalizacja (1NF, 2NF, 3NF) ogranicza redundancję i zapewnia spójność struktury, ale silnie znormalizowane modele mogą wymagać nadmiernej liczby złączeń. Denormalizacja może przyspieszyć obciążenia zdominowane przez odczyty.

4.2 Dobór typów danych

Wybór typu danych bezpośrednio wpływa na zajmowane miejsce:

TypBajtyUwagi
int4Standardowa liczba całkowita
smallint2Wydajny dla ograniczonego zakresu
tinyint1Tylko 0–255
nvarchar(max)zmiennaUnikać, jeśli nie jest konieczny

4.3 Partycjonowanie tabel

Strategie partycjonowania obejmują partycjonowanie zakresowe (np. po czasie), listowe (kategorie) i haszowe (rozkład). Formalnie partycjonowanie dzieli tabelę T na rozłączne części:

T = P₁ ∪ P₂ ∪ … ∪ Pₖ,   gdzie Pᵢ ∩ Pⱼ = ∅ dla i ≠ j

5. Optymalizacja indeksów

Indeksowanie to metoda optymalizacji o największym wpływie.

5.1 Rodzaje indeksów

SQL Server 2022 obsługuje indeksy klastrowe, nieklastrowe, kolumnowe (columnstore), filtrowane i zoptymalizowane pod pamięć.

Eksperyment 1: wpływ indeksu nieklastrowego. Skrypt porównuje koszt tego samego zapytania przed utworzeniem i po utworzeniu indeksu nieklastrowego z kolumnami INCLUDE. Porównaj wyniki SET STATISTICS IO, TIME oraz plany wykonania obu uruchomień.

-- Eksperyment 1: Wpływ indeksu nieklastrowanego na wydajność

-- 1. Tabela testowa (symulacja tabeli transakcyjnej)
IF OBJECT_ID('dbo.SalesBig', 'U') IS NOT NULL
    DROP TABLE dbo.SalesBig;
GO

CREATE TABLE dbo.SalesBig
(
    SalesId     BIGINT        IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    CustomerId  INT           NOT NULL,
    OrderDate   DATETIME2(0)  NOT NULL,
    Amount      DECIMAL(18,2) NOT NULL,
    Status      CHAR(1)       NOT NULL
);
GO

-- 2. Wypełnienie danymi (1 mln wierszy)
INSERT INTO dbo.SalesBig (CustomerId, OrderDate, Amount, Status)
SELECT TOP (1000000)
    ABS(CHECKSUM(NEWID())) % 50000                                  AS CustomerId,
    DATEADD(DAY, -ABS(CHECKSUM(NEWID())) % 365, SYSDATETIME())       AS OrderDate,
    CAST(ABS(CHECKSUM(NEWID())) % 100000 / 100.0 AS DECIMAL(18,2))   AS Amount,
    CASE WHEN ABS(CHECKSUM(NEWID())) % 10 = 0 THEN 'R' ELSE 'C' END  AS Status
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
GO

-- 3. Zapytanie bazowe BEZ indeksu
SET STATISTICS IO, TIME ON;
GO
SELECT  CustomerId, SUM(Amount) AS TotalAmount
FROM    dbo.SalesBig
WHERE   Status = 'C'
  AND   OrderDate >= DATEADD(DAY, -30, SYSDATETIME())
GROUP BY CustomerId;
GO
SET STATISTICS IO, TIME OFF;
GO

-- 4. Tworzymy indeks nieklastrowany z INCLUDE
CREATE NONCLUSTERED INDEX IX_SalesBig_Status_OrderDate
ON dbo.SalesBig (Status, OrderDate)
INCLUDE (Amount, CustomerId);
GO

-- 5. To samo zapytanie PO utworzeniu indeksu
SET STATISTICS IO, TIME ON;
GO
SELECT  CustomerId, SUM(Amount) AS TotalAmount
FROM    dbo.SalesBig
WHERE   Status = 'C'
  AND   OrderDate >= DATEADD(DAY, -30, SYSDATETIME())
GROUP BY CustomerId;
GO
SET STATISTICS IO, TIME OFF;
GO

W obciążeniach analitycznych indeksy kolumnowe mogą być wielokrotnie szybsze od rowstore — przykładowe porównanie w oryginalnym notatniku zakłada 12-krotne przyspieszenie.

5.2 Fragmentacja i utrzymanie

Fragmentacja pogarsza wydajność odczytów. Typowa reguła:

FragmentacjaDziałanie
0–10%Brak
10–30%REORGANIZE
> 30%REBUILD
ALTER INDEX ALL ON TableName REBUILD;

Przykładowe dane pokazujące, jak czas zapytania rośnie wraz z fragmentacją:

Fragmentacja (%)0102030406080
Czas zapytania (ms)100110130160200280400

5.3 Selektywność indeksu

Selektywność to jedna z kluczowych miar decydujących o tym, czy indeks będzie skuteczny:

S = liczba unikalnych wartości / łączna liczba wierszy

Wysoka selektywność (bliska 1,0) oznacza, że kolumna zawiera głównie unikalne wartości — indeks nieklastrowy najpewniej zadziała bardzo dobrze. Niska selektywność (bliska 0) oznacza wiele powtórzeń, przez co indeks jest znacznie mniej użyteczny.

Eksperyment 2: pomiar fragmentacji i selektywności.

-- Eksperyment 2: Pomiar fragmentacji i selektywności indeksów

-- Fragmentacja fizyczna indeksów
SELECT
    DB_NAME(ips.database_id)         AS DatabaseName,
    OBJECT_NAME(ips.object_id)       AS TableName,
    i.name                           AS IndexName,
    ips.index_type_desc,
    ips.avg_fragmentation_in_percent,
    ips.page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'SAMPLED') AS ips
JOIN sys.indexes AS i
    ON ips.object_id = i.object_id
   AND ips.index_id  = i.index_id
WHERE ips.page_count > 1000
ORDER BY ips.avg_fragmentation_in_percent DESC;
GO

-- Selektywność (przybliżona) na podstawie statystyk
SELECT
    OBJECT_NAME(s.object_id)   AS TableName,
    i.name                     AS IndexName,
    s.stats_id,
    sp.rows,
    sp.rows_sampled,
    sp.steps,
    CAST(sp.rows_sampled AS FLOAT) / NULLIF(sp.rows, 0) AS SampleRatio
FROM sys.stats AS s
JOIN sys.indexes AS i
    ON s.object_id = i.object_id
   AND s.stats_id  = i.index_id
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE s.object_id = OBJECT_ID('dbo.SalesBig');
GO

6. Optymalizacja TempDB

TempDB to jedna z najintensywniej używanych baz w SQL Server. Sortowanie, haszowanie, wersjonowanie wierszy, wyniki pośrednie zapytań, wyzwalacze i tabele tymczasowe — wszystko to zależy od jej wydajności.

6.1 Dobre praktyki

RekomendacjaOpis
Wiele plików danychTyle plików, ile rdzeni CPU, maksymalnie 8
Równe rozmiary plikówZapobiega nierównomiernej alokacji
Instant File InitializationPrzyspiesza powiększanie plików TempDB
Dyski SSD/NVMeZnacząco zmniejszają opóźnienia I/O

Diagnostyka konfiguracji TempDB:

-- Pliki tempdb i ich rozmiary
SELECT
    name,
    type_desc,
    size * 8 / 1024   AS SizeMB,
    max_size,
    growth * 8 / 1024 AS GrowthMB,
    is_percent_growth
FROM tempdb.sys.database_files;
GO

-- Aktywne alokacje w TempDB
SELECT
    session_id,
    task_allocations_page_count,
    task_deallocations_page_count
FROM sys.dm_db_task_space_usage
ORDER BY task_allocations_page_count DESC;
GO

Przykładowa przepustowość w zależności od liczby plików danych TempDB:

Liczba plików1248
Przepustowość (MB/s)100170250310

6.2 Model rywalizacji o zasoby TempDB

Gdy alokacje są rozłożone na wiele plików, prawdopodobieństwo rywalizacji maleje mniej więcej proporcjonalnie do liczby plików:

C ≈ 1 / F

C — prawdopodobieństwo rywalizacji (contention)
F — liczba plików danych TempDB

Więcej plików danych to mniej rywalizacji o zatrzaski (latch contention) i lepsza współbieżność.

7. Optymalizacja pamięci

SQL Server 2022 oferuje zaawansowane funkcje pamięci, w tym In-Memory OLTP, usprawnione zarządzanie buforem i hybrydowe rozszerzenia pamięci.

7.1 In-Memory OLTP

In-Memory OLTP eliminuje zatrzaski i blokady dzięki wielowersyjnej kontroli współbieżności (MVCC). Tabele zoptymalizowane pod pamięć mogą zapewnić:

  • 5–30 razy szybsze wstawianie,
  • około 10 razy szybsze odczyty,
  • przewidywalne opóźnienia przy dużej współbieżności.

Przykładowe porównanie z notatnika:

Operacje na sekundęTabele dyskoweTabele w pamięci
Odczyty/s2 00018 000
Zapisy/s1 2008 000

7.2 Bufor i model buforowania

Uproszczony model współczynnika trafień w buforze (buffer pool hit ratio):

H ≈ M / D

H — współczynnik trafień w buforze
M — dostępna pamięć
D — rozmiar zbioru danych

Gdy M ≈ D, większość odczytów obsługuje RAM i wydajność jest bardzo dobra. Gdy M ≪ D, SQL Server wykonuje więcej odczytów fizycznych i wydajność spada.

7.3 Buffer Pool Extension (BPE)

Buffer Pool Extension pozwala używać dysku SSD jako rozszerzenia pamięci RAM. Pomaga przy ograniczonej pamięci, choć pozostaje wolniejszy od prawdziwej pamięci RAM.

8. Optymalizacja storage’u

Pamięć masowa to jeden z najważniejszych czynników wydajności SQL Server.

8.1 SSD i NVMe

Dyski SSD/NVMe o niskich opóźnieniach zmniejszają całkowity koszt I/O (C_IO ∝ opóźnienie). Dyski NVMe osiągają opóźnienia rzędu mikrosekund, co wyraźnie poprawia wydajność checkpointów, przepustowość TempDB oraz operacje sortowania i haszowania.

8.2 Kompresja

SQL Server obsługuje kompresję wierszy, stron i kolumnową. Kompresja zmniejsza rozmiar tabel, liczbę operacji dyskowych i zużycie pamięci — kosztem potencjalnie większego obciążenia CPU.

8.3 Instant File Initialization

Po włączeniu IFI SQL Server może powiększać pliki danych bez zerowania przestrzeni dyskowej, co przyspiesza autogrowth, tworzenie baz i odtwarzanie kopii.

9. Narzędzia monitorowania i DMV

9.1 Dynamic Management Views

DMVPrzeznaczenie
sys.dm_exec_query_statsMetryki wydajności zapytań
sys.dm_exec_requestsAktualnie wykonywane żądania
sys.dm_db_index_usage_statsŚledzenie użycia indeksów
sys.dm_os_wait_statsAnaliza statystyk oczekiwań (waitów)

Eksperyment 3: analiza głównych waitów w systemie.

-- Eksperyment 3: Analiza głównych waitów w systemie
WITH Waits AS
(
    SELECT
        wait_type,
        wait_time_ms - signal_wait_time_ms AS resource_wait_ms,
        signal_wait_time_ms                AS signal_wait_ms
    FROM sys.dm_os_wait_stats
    WHERE wait_type NOT IN
    (
        'SLEEP_TASK','SLEEP_SYSTEMTASK','SQLTRACE_BUFFER_FLUSH',
        'BROKER_TASK_STOP','BROKER_TO_FLUSH','BROKER_EVENTHANDLER',
        'XE_TIMER_EVENT','XE_DISPATCHER_WAIT','BROKER_RECEIVE_WAITFOR',
        'ONDEMAND_TASK_QUEUE','FT_IFTS_SCHEDULER_IDLE_WAIT',
        'BROKER_TRANSMITTER','CHECKPOINT_QUEUE',
        'CLR_AUTO_EVENT','CLR_MANUAL_EVENT','LAZYWRITER_SLEEP',
        'SLEEP_BPOOL_FLUSH'
    )
)
SELECT TOP (10)
    wait_type,
    resource_wait_ms / 1000.0                    AS resource_wait_s,
    signal_wait_ms   / 1000.0                    AS signal_wait_s,
    (resource_wait_ms + signal_wait_ms) / 1000.0 AS total_wait_s
FROM Waits
ORDER BY total_wait_s DESC;
GO

9.2 Query Store

Query Store zapisuje plany zapytań, regresje i metryki wykonania. Pozwala wymusić wcześniejszy plan, gdy SQL Server wygeneruje gorszy.

9.3 Extended Events

Extended Events to elastyczny i lekki mechanizm śledzenia, który zastępuje SQL Profiler.

10. Porównanie technik optymalizacji

Przybliżone zyski wydajności dla kluczowych funkcji:

Technika optymalizacjiZysk wydajnościTypowe zastosowanie
Indeks kolumnowy (columnstore)5×–40×OLAP, raportowanie
Tryb wsadowy (batch mode)4×–20×Agregacje, analityka
In-Memory OLTP~10×Wysoko obciążony OLTP
Parameter Sensitive Plan Optimization2×–5×Zmienne obciążenia
Strojenie TempDB1,5×–3×Obciążenia ogólne

11. Podsumowanie

SQL Server 2022 to nowa generacja inteligentnej optymalizacji baz danych. Łącząc zaawansowane indeksowanie, inteligentne przetwarzanie zapytań, lepsze zarządzanie pamięcią i storage’em, optymalizację TempDB oraz rozbudowane narzędzia monitorowania, organizacje mogą osiągnąć znaczący wzrost wydajności zarówno w obciążeniach OLTP, jak i OLAP.

Najważniejsze wnioski:

  1. Intelligent Query Processing usuwa wiele historycznych wąskich gardeł wydajności.
  2. Prawidłowe indeksowanie pozostaje fundamentem strojenia wydajności.
  3. Konfiguracja TempDB i storage’u znacząco wpływa na całkowitą przepustowość.
  4. Nowoczesny sprzęt (NVMe, wielordzeniowe CPU) dobrze współgra z funkcjami SQL Server 2022.
  5. Funkcje adaptacyjne i automatyczne zmniejszają potrzebę ręcznej optymalizacji.

Bibliografia

  1. Microsoft Corporation, SQL Server 2022 Technical Documentation, 2023.
  2. K. Tripp, SQL Server Query Performance Tuning, O’Reilly Media, 2022.
  3. I. Ben-Gan, T-SQL Querying and Query Tuning, Microsoft Press, 2020.
  4. P. Larsson, „Columnstore Index Strategies”, SQLSkills, 2022.
  5. G. Lewin, „Adaptive Query Processing in SQL Server”, MSDN Magazine, 2021.
  6. ISO/IEC 9075-1, SQL Standard, 2016.

Wykresy w oryginalnym notatniku korzystają z przykładowych danych — powyższe tabele zawierają te same wartości. Pełny notatnik z kodem do uruchomienia jest dostępny w Google Colab (link w panelu bocznym).

AŁ
Artur ŁaskiDyrektor IT, właściciel MAKE IT EASY, doktorant Computer Science & AI.
Napisz do mnie