{"id":1502,"date":"2008-09-30T21:36:02","date_gmt":"2008-09-30T19:36:02","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/?p=1502"},"modified":"2008-09-29T22:20:16","modified_gmt":"2008-09-29T20:20:16","slug":"count-aber-schnell","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2008\/09\/30\/sql-talk\/sql-tools\/count-aber-schnell","title":{"rendered":"COUNT, aber schnell!"},"content":{"rendered":"<p>&#220;ber den <a href=\"http:\/\/www.sqlpass.de\/newsletter\/Newsletter_2008_10.pdf\">aktuellen SQL-Pass-Newsletter<\/a> wurde ich auf den absolut interessanten Trick aufmerksam, wie man sehr schnell (im Sinne von &quot;sehr performant&quot;) die Anzahl von Datens&#228;tzen in einer Tabelle ermittelt. Aber leider ist der Autor dem gleichen Fehler aufgesessen, wie ich zu Beginn meiner SQL-Server-Zeit. <\/p>\n<p>Der erw&#228;hnte Trick ist sehr ausf&#252;hrlich im Artikel &quot;<a href=\"http:\/\/www.sql-server-performance.com\/articles\/per\/Speeding_up_the_Performance_of_Table_Counts_p1.aspx\">Speeding up the Performance of Table Counts in SQL Server 2005<\/a>&quot; beschrieben. M&#246;glicherweise ist er mit richtig vielen Datens&#228;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&#228;tzten Kosten. Sie sind nicht richtig.<\/p>\n<p>Wenn ich den Trick ausf&#252;hre und den COUNT, dann zeigt auch mein Zugriffsplan in den gesch&#228;tzten Werten an, dass der Trick schneller sei (der Code ist <a href=\"http:\/\/www.sql-server-performance.com\/articles\/per\/Speeding_up_the_Performance_of_Table_Counts_p1.aspx\">aus dem Artikel<\/a> abgeleitet, nur leicht vereinfacht):<\/p>\n<p><code lang=\"sql\">-- Trick:<br \/>\nSELECT  SUM( p.rows )<br \/>\n FROM       sys.partitions p<br \/>\n LEFT JOIN  sys.allocation_units a<br \/>\n        ON  p.partition_id = a.container_id<br \/>\n WHERE  p.index_id  IN (0,1) &#8211; 0 heap table , 1 table with clustered index<br \/>\n  AND   p.rows IS NOT NULL<br \/>\n  AND   a.type = 1           &#8211; row-data only , not LOB<br \/>\n  AND   p.object_id = object_id(&#x0027;Person.Address&#x0027;)<br \/>\n&#8211; Hat &quot;estimated subtree cost&quot; von 0.028<br \/>\ngo<br \/>\n&#8211; regul&#228;r:<br \/>\nSELECT COUNT(*)<br \/>\n\tFROM Person.Address<br \/>\n&#8211; Hat &quot;estimated subtree cost&quot; von 0.055<\/code><\/p>\n<p>Wegen der &quot;<strong>estimated<\/strong> subtree cost&quot; zeigt das Management-Studio an, dass der erste Batch 33% der Zeit und der zweite 67% in Anspruch n&#228;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 <strong>gesch&#228;tzten<\/strong> Kosten wieder. Wenn man die echte Zeit wissen will, dann muss man schon zu Kommissar Profiler gehen&#8230; \ud83d\ude09<\/p>\n<p>PS: Schade, dass der Autor weder Kommentare zulie&#223;, noch eine Mail-Adresse angab. Daraus schlie&#223;e ich, dass er keinen Dialog w&#252;nscht. Ist das eine zul&#228;ssige Annahme?<\/p>\n<p>PPS: Ich sehe gerade, dass sich <a href=\"http:\/\/blogs.technet.com\/steffenk\/archive\/2008\/09\/06\/sql-server-mythen-die-count-debatte.aspx\">Steffen Krause ein paar Tage vorher<\/a> mit dem gleichen Thema besch&#228;ftigte. Welch lustige Koinzidenz &#8211; er ber&#252;cksichtigt aber die BLOBs nicht. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#220;ber den aktuellen SQL-Pass-Newsletter wurde ich auf den absolut interessanten Trick aufmerksam, wie man sehr schnell (im Sinne von &quot;sehr performant&quot;) die Anzahl von Datens&#228;tzen in einer Tabelle ermittelt. Aber leider ist der Autor dem gleichen Fehler aufgesessen, wie ich zu Beginn meiner SQL-Server-Zeit. Der erw&#228;hnte Trick ist sehr ausf&#252;hrlich im Artikel &quot;Speeding up the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[14],"tags":[310,312,929,311],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/1502"}],"collection":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/comments?post=1502"}],"version-history":[{"count":6,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/1502\/revisions"}],"predecessor-version":[{"id":1509,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/1502\/revisions\/1509"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=1502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=1502"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=1502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}