Craig Freedman herlezen: de queryprocessor-blog die na twintig jaar nog klopt
Tussen 2006 en 2010 schreef Craig Freedman — destijds ontwikkelaar in het SQL Server Query Optimizer-team van Microsoft — de misschien wel beste reeks blogposts die er ooit over queryverwerking is verschenen. Geen marketingpraat, maar iemand die de optimizer van binnenuit kende en post voor post uitlegde waarom SQL Server doet wat het doet: hoe iterators samenwerken, waarom een hash join soms wint van een merge join, wat er écht gebeurt bij parallellisme.
De blog is inmiddels alleen nog als archief op learn.microsoft.com te vinden, en dat is zonde. Daarom heb ik de complete serie herlezen — en belangrijker: elk concept opnieuw getest op moderne SQL Server-versies, met echte executieplannen. De uitkomst na tien artikelen: vrijwel alles staat nog overeind. De queryprocessor die Freedman in 2006 beschreef, is in de kern dezelfde die vandaag jouw plannen bouwt. Wie zijn serie begrijpt, leest élk executieplan met andere ogen.
Hieronder de leeswijzer bij alle tien delen. Ben je nieuw in executieplannen: begin gewoon bij deel 1, de serie is bewust chronologisch opgebouwd. Zoek je een specifiek onderwerp — joins, parallellisme, isolation levels — spring dan direct naar het deel dat erover gaat. (Alle artikelen zijn Engelstalig.)
2006: de fundamenten, van iterator tot parallellisme
- Juni 2006: The Foundations — Het mentale model waar alles op rust: de iterator-boom, plannen lezen (grafisch, tekst, XML), scans versus seeks en de beruchte bookmark lookup. Verplichte kost.
- Juli 2006: From Indexes to Joins — Van indexgebruik naar de eerste join: hoe de nested loops join werkt en wanneer de optimizer ervoor kiest.
- Augustus 2006: Merge Join, Hash Join and Subqueries — De andere twee join-operators, hun geheugengedrag, en hoe subqueries onder de motorkap tot joins worden herschreven.
- September 2006: Aggregation — Stream aggregate versus hash aggregate: waarom sortering het verschil maakt en wat dat betekent voor GROUP BY en DISTINCT.
- Oktober 2006: Decorrelation, Index Union and the Exchange Operator — De optimizer als herschrijver: gecorreleerde subqueries ontvlochten, meerdere indexen gecombineerd, en de exchange-operator die parallellisme mogelijk maakt.
- November 2006: Parallel Scans, Parallel Joins and Partitioned Tables — Hoe SQL Server werk over threads verdeelt: parallelle scans en joins, en de wisselwerking met gepartitioneerde tabellen.
- December 2006: The Semi-join Transformation — Eén transformatie uitgediept: hoe EXISTS en IN als semi-join worden uitgevoerd en waarom dat sneller is dan je eigen omweg.
2007–2010: van isolation levels tot de slotposts
- 2007: Isolation Levels, PIVOT, TOP, Index Maintenance and CTEs — Het breedste jaar: wat isolation levels werkelijk garanderen, hoe PIVOT en TOP in het plan belanden, index-onderhoud en recursieve CTE's.
- 2008: Ranking Functions, Conversions, Partitioning and I/O — ROW_NUMBER en vrienden in het plan, de valkuilen van impliciete conversies, partitioning en hoe I/O een query maakt of breekt.
- 2009–2010: I/O by Sorting, Hint Pitfalls and the Final Posts — Het slotakkoord: random I/O temmen door te sorteren, waarom hints vaker kwaad dan goed doen, en de laatste posts van een serie die het herlezen meer dan waard bleek.
Waarom dit nog steeds relevant is
SQL Server heeft er sinds 2010 veel bij gekregen — columnstore, batch mode, Intelligent Query Processing, Azure SQL — maar de row-mode-operators waar Freedman over schreef zitten nog steeds in negen van de tien plannen die ik als DBA onder ogen krijg. Een nested loops join werkt in SQL Server 2025 nog precies zoals hij in 2006 werkte. Dat is precies wat deze serie zo waardevol maakt: het is geen versie-kennis die veroudert, maar fundament-kennis die blijft.
De volledige serie staat gebundeld op dbaronald.nl/category/craig-freedman.
Loop je in de praktijk vast op een executieplan dat je niet kunt verklaren? Ik kijk graag even mee.