Über den aktuellen SQL-Pass-Newsletter wurde ich auf den absolut interessanten Trick aufmerksam, wie man sehr schnell (im Sinne von "sehr performant") die Anzahl von Datensätzen in einer Tabelle ermittelt. Aber leider ist der Autor dem gleichen Fehler aufgesessen, wie ich zu Beginn meiner SQL-Server-Zeit.

Der erwähnte Trick ist sehr ausführlich im Artikel "Speeding up the Performance of Table Counts in SQL Server 2005" beschrieben. Möglicherweise ist er mit richtig vielen Datensätzen auch wirklich schneller als COUNT, aber ich kann es mir kaum denken. Das ist aber gar nicht so wichtig, weil meine Message ist: Vorsicht vor den geschätzten Kosten. Sie sind nicht richtig.

Wenn ich den Trick ausführe und den COUNT, dann zeigt auch mein Zugriffsplan in den geschätzten Werten an, dass der Trick schneller sei (der Code ist aus dem Artikel abgeleitet, nur leicht vereinfacht):

-- Trick:
SELECT SUM( p.rows )
FROM sys.partitions p
LEFT JOIN sys.allocation_units a
ON p.partition_id = a.container_id
WHERE p.index_id IN (0,1) – 0 heap table , 1 table with clustered index
AND p.rows IS NOT NULL
AND a.type = 1 – row-data only , not LOB
AND p.object_id = object_id('Person.Address')
– Hat "estimated subtree cost" von 0.028
go
– regulär:
SELECT COUNT(*)
FROM Person.Address
– Hat "estimated subtree cost" von 0.055

Wegen der "estimated subtree cost" zeigt das Management-Studio an, dass der erste Batch 33% der Zeit und der zweite 67% in Anspruch nähme. Das stimmt aber gar nicht. Der SQL-Profiler bringt es ans Licht: Der erste Batch dauert 35ms und der zweite nur 9ms. Der Prozentwert im Management-Studio spiegelt nur die geschätzten Kosten wieder. Wenn man die echte Zeit wissen will, dann muss man schon zu Kommissar Profiler gehen… 😉

PS: Schade, dass der Autor weder Kommentare zuließ, noch eine Mail-Adresse angab. Daraus schließe ich, dass er keinen Dialog wünscht. Ist das eine zulässige Annahme?

PPS: Ich sehe gerade, dass sich Steffen Krause ein paar Tage vorher mit dem gleichen Thema beschäftigte. Welch lustige Koinzidenz – er berücksichtigt aber die BLOBs nicht.