Technisch artikel
Een SQL Server-query optimaliseren met uitvoeringsplannen
Combineer uitvoeringsplannen, logical reads en gecontroleerde tests. Een seek of een groen indexadvies is op zichzelf geen bewijs van verbetering.
- SQL
- SQL Server

In dit artikel
Verzamel bewijs vóór je een index toevoegt
Een SQL Server-query optimaliseren vraagt meer dan zoeken naar een tabelscan. Leg de query, parametertypes, databaseversie, compatibiliteitsniveau, indexen en dataverdeling vast. Noteer of de vertraging altijd voorkomt of alleen bij bepaalde klanten en momenten. Wachttijd door blokkering vraagt een andere aanpak dan veel logical reads. Het onderstaande voorbeeld gebruikt een tijdelijke tabel met fictieve bestellingen. Het illustreert een gecontroleerde vergelijking; het rapporteert geen gemeten klantresultaat en is geen productieadvies voor jouw schema.
Geschat plan, werkelijk plan en statistieken
Een geschat uitvoeringsplan bevat geen runtime-metingen van de uitgevoerde query. Een werkelijk uitvoeringsplan verzamelt gegevens tijdens uitvoering: de query wordt dus ook echt uitgevoerd. Gebruik daarvoor een veilige testomgeving en de benodigde rechten. SET STATISTICS IO toont onder meer logical reads, de pagina’s die uit de datacache gelezen worden. SET STATISTICS TIME toont CPU- en verstreken tijden. Het aantal teruggegeven records is niet hetzelfde als het aantal gelezen pagina’s. Vergelijk beide informatiebronnen met dezelfde query en data.
-- SQL Server example. Use a NEW session in a separate test database.
-- Never run this in production. Stop on the first error and close the session.
-- Enable Include Actual Execution Plan in your SQL client before running.
CREATE TABLE #cg_sqlserver_orders (
id int NOT NULL PRIMARY KEY,
customer_id int NOT NULL,
created_at datetime2(0) NOT NULL
);
INSERT INTO #cg_sqlserver_orders VALUES
(1,42,'2026-08-31T23:59:59'), (2,42,'2026-09-01T00:00:00'),
(3,42,'2026-09-01T12:00:00'), (4,42,'2026-09-01T12:00:00'),
(5,42,'2026-09-02T00:00:00'), (6,7,'2026-09-01T12:00:00'),
(7,42,'2026-09-01T23:59:59'), (8,42,'2026-09-02T00:00:01');
DECLARE @customer_id int = 42;
DECLARE @from datetime2(0) = '2026-09-01T00:00:00';
DECLARE @until datetime2(0) = '2026-09-02T00:00:00';
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT id, customer_id, created_at FROM #cg_sqlserver_orders
WHERE customer_id = @customer_id AND created_at >= @from AND created_at < @until
ORDER BY created_at DESC, id DESC;
CREATE INDEX cg_sqlserver_customer_date_id
ON #cg_sqlserver_orders(customer_id, created_at, id);
SELECT id, customer_id, created_at FROM #cg_sqlserver_orders
WHERE customer_id = @customer_id AND created_at >= @from AND created_at < @until
ORDER BY created_at DESC, id DESC;
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
-- Expected IDs in both results: 7, 4, 3, 2. Inspect each SELECT separately.
-- Index creation also produces messages; do not confuse them with SELECT costs.
-- Eight rows cannot establish a production speedup. A scan can be appropriate.Lees operators in hun context
Vergelijk geschatte en werkelijke aantallen bij relevante operators. Grote afwijkingen kunnen aanleiding zijn om statistieken, parameters en dataverdeling te onderzoeken. Kijk naar residual predicates, sorteringen, spills en eventuele impliciete conversies, maar verklaar eerst waarom ze optreden. Een seek met veel aanvullende lookups kan duurder zijn dan een scan. Een missing-index-suggestie is slechts een onderzoekspunt en houdt niet automatisch rekening met alle schrijfkosten of overlappende indexen. Wijzig niet tegelijk query, indexen en serverinstellingen als je het effect van één ingreep wilt begrijpen.
Valideer verschillende parameters en dezelfde uitkomst
De demonstratie verwacht ID’s 7, 4, 3 en 2. Ze bevat een andere klant, de begin- en eindgrens en gelijke tijdstippen. Test in een echte toepassing ook kleine en grote klanten, vaak en zelden voorkomende waarden en lege resultaten. Parameterafhankelijke plannen kunnen verschillende prestaties geven. Het opnieuw compileren of forceren van een plan is geen standaardoplossing zonder analyse. Controleer de businessuitkomst en toegangsbeperkingen, niet alleen het aantal rijen of een aantrekkelijker planplaatje.
Maak de wijziging beheersbaar
Meet meerdere runs met beschreven cachecondities en gelijktijdige belasting. Wis geen productiecache om een vergelijking mooier te maken. Vergelijk daarna ook inserts, updates en indexruimte. Spreek een terugvalprocedure en stopcriteria af voordat een productie-index wordt gewijzigd. Dit T-SQL-voorbeeld is hier niet tegen SQL Server uitgevoerd; de getoonde verwachte ID’s beschrijven de fixturelogica, geen gevalideerd SQL Server-plan of timing. Pas versie, rechten en schema expliciet aan de echte omgeving aan.
Verder onderzoeken
Een queryplan is één deel van de diagnose. Hieronder vind je aanvullende uitleg en een afgebakende SQL-dienst. De demonstraties gebruiken fictieve gegevens, niet de resultaten van een klantproject. Deel bij een aanvraag alleen een probleembeschrijving en geanonimiseerde context; geen wachtwoorden, volledige dumps of persoonsgegevens.
Laatst bijgewerkt:


