📖 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:
- Index Seek: Najbolje. Baza ide direktno na podatak koristeći B-Tree.
- Index Scan: Lošije. Prolazi kroz cijeli indeks (obično fali WHERE klauzula).
- Key Lookup: Upozorenje! Baza je našla podatak u indeksu, ali mora ići u tabelu po ostale kolone (potreban Covered Index).
- Hash Match: Teška operacija spajanja (JOIN) miliona redova u memoriji.
📊 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.
-- 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:
- PSP Optimization: Rješava problem Parameter Sniffing-a tako što čuva više planova za istu proceduru (npr. jedan za male, jedan za velike klijente).
- DOP Feedback: Baza sama uči i smanjuje broj procesora (Degree of Parallelism) ako primijeti da upit guši server.
- Memory Grant Feedback: Ako upit traži previše memorije (ili premalo pa ide na disk), baza to popravlja u sljedećem izvršavanju.
🎯 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).
-- 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:
- ✅ Execution Plan je vaša "rendgenska slika" upita.
- ✅ Query Store vas spašava od panike kada performanse "padnu preko noći".
- ✅ Moderni SQL 2022 radi 50% posla umjesto vas kroz IQP.
📚 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.