MODUL 5 - LEKCIJA 2

Optimizacija Performansi Upita

Od Execution Planova do Query Store-a i Intelligent Query Processing-a

⏱️ Trajanje: ~4 časa 📚 Nivo: Napredni 🎯 Praktični primjeri: 6

📖 Sudbina Upita

Kada pošaljete SQL upit, on prolazi kroz tri faze: 1. Parsing: Provjera sintakse. 2. Binding (Algebrization): Provjera da li tabele i kolone postoje. 3. Optimization: Najvažnija faza gdje Query Optimizer bira najjeftiniji put (Execution Plan) na osnovu statistika.

📉 Anatomija Execution Plana

Plan izvršenja vam grafički pokazuje šta baza stvarno radi. Ključni operatori su:

📊 Statistike su oči baze

SQL Server zna da li u tabeli ima 10 ili 10 miliona redova zahvaljujući statistikama. Ako su statistike stare (Out-of-date), Optimizer će izabrati pogrešan plan. Uvijek provjerite UPDATE STATISTICS ako upit iznenada uspori.

📓 Query Store: Crna kutija

Predstavljen u ranijim verzijama, a u SQL 2022 je uključen po defaultu za svaku novu bazu. On snima istoriju svih planova i trajanje svakog upita.

🛠️ Pronalaženje upita kojima su performanse opale (Regression)
-- SQL Server Management Studio (SSMS) ima Query Store vizuelni dashboard
-- ali možete upiti i direktno:
SELECT 
    q.query_id, 
    qt.query_sql_text, 
    p.plan_id, 
    rs.avg_duration
FROM sys.query_store_query q
JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
JOIN sys.query_store_plan p ON q.query_id = p.query_id
JOIN sys.query_store_runtime_stats rs ON p.plan_id = rs.plan_id
WHERE rs.last_execution_time > DATEADD(hour, -24, GETDATE())
ORDER BY rs.avg_duration DESC;

🧠 Intelligent Query Processing (IQP) u 2022

SQL Server 2022 donosi "samoiscjeljujuće" upite:

🎯 Praktična Vježba: Detekcija sporog upita

Zadatak: Eliminacija 'Table Scan' operacije

Upit SELECT * FROM Reports WHERE ReportYear = 2023 je spor. Analizom plana vidite Table Scan uprkos tome što imate indeks na CreatedDate.

Problem: Korištenje funkcije YEAR() na koloni indeksa čini upit non-SARGable (Optimizer ne može koristiti indeks).

💡 Rješenje (Optimizacija koda)
-- LOŠE (Table Scan)
SELECT * FROM Stats.Reports WHERE YEAR(CreatedDate) = 2023;

-- ODLIČNO (Index Seek)
SELECT * FROM Stats.Reports 
WHERE CreatedDate >= '20230101' AND CreatedDate < '20240101';

-- Pravilo: Nikada ne stavljajte funkciju nad kolonom u WHERE klauzuli!

✅ Zaključak

Optimizacija je kontinuiran proces, a ne jednokratan posao:

📚 Sljedeća Lekcija

U Lekciji 5.3 prelazimo na Sigurnost. Naučićete kako implementirati Row-Level Security i Data Masking kako bi zaštitili osjetljive podatke od neovlaštenih očiju.