{"id":58,"date":"2009-03-03T12:07:28","date_gmt":"2009-03-03T11:07:28","guid":{"rendered":"http:\/\/csopro.de\/biblog\/2009\/03\/performance-und-guids\/"},"modified":"2014-12-31T18:30:52","modified_gmt":"2014-12-31T17:30:52","slug":"performance-und-guids","status":"publish","type":"post","link":"https:\/\/www.csopro.de\/biblog\/2009\/03\/performance-und-guids\/","title":{"rendered":"Performance und GUIDs"},"content":{"rendered":"<p>In einem Kunden-Projekt sollte ich die Performance der SQL-Zugriffe einer .NET-Applikation verbessern.<\/p>\n<p>Hier beschreibe ich die Ergebnisse, da sie sich auch auf andere Szenarien verallgemeinern lassen.<\/p>\n<p>Die erste Ver\u00e4nderung war, <strong>keine GUIDs<\/strong> als <strong>clustered primary keys<\/strong> zu verwenden. Stattdessen setzen wir nun ints (mit Identity) ein. Dies f\u00fchrt zu einer immensen Beschleunigung bei den INSERTs in die Datenbank. Dies ist sehr gut nachvollziehbar, da nun die INSERTs immer am Ende der Tabelle statttfinden, so dass kein zeitaufw\u00e4ndiges Umorganisieren der Seiten innerhalb der Tabelle notwendig wird.<\/p>\n<p>Leider ging es aber in meiner Aufgabe um die SELECT-Performance und nicht um die INSERT-Performance. Aber auch diese verbesserte sich durch die Verwendung der integer-Werte deutlich (Abfragezeit ungef\u00e4hr halbiert). Als Test verwendete ich die Abfrage von 500 Datens\u00e4tzen, die ich zu Beginn zuf\u00e4llig ausgew\u00e4hlt hatte. Vor jeder Abfrage wurde nat\u00fcrlich der Cache geleert \ud83d\ude42 Die Steigerung l\u00e4sst sich dadurch erkl\u00e4ren, dass alle Indizes nun vom Platzbedarf viel kleiner wurden (1 int = 4 byte, 1 guid = 16 byte &#8211;&gt; ca. 4x so viele Daten gehen auf eine Index-Page [nat\u00fcrlich abh\u00e4ngig von den weiteren Feldern des Index]). Au\u00dferdem ist ein Z\u00e4hler besser verteilt als eine Guid.<\/p>\n<p>Als n\u00e4chste Verbesserung verwendete ich in <strong>m:n-Tabellen<\/strong> als clustered primary key nicht einen Z\u00e4hler, sondern einen <strong>zusammengesetzten Schl\u00fcssel<\/strong> aus den beiden referenzierten Tabellen (+ ein weiteres Feld, um die Eindeutigkeit sicherzustellen). Dabei verwendete ich als erstes Feld das Feld der beiden, das in den meisten Abfragen bekannt ist. (Auf der umgekehrten Reihenfolge lag nat\u00fcrlich auch ein Index). Dadurch muss beim Standard-Zugriff nicht mehr \u00fcber einen non-clustered Index zugegriffen werden, wodurch ein Zugriff eingespart wird. Dies brachte eine weitere Halbierung der Zugriffszeit.<\/p>\n<p>ALs letztes gab es spezielle Szenarien, in denen nach Texten gesucht werden musste &#8211; ein Beispiel: Man m\u00f6chte alle Auftr\u00e4ge ermitteln, die in einer Position einen bestimmten Positionsfreitext enthalten. Dann wird folgendes SQL-Statement abgesetzt:<\/p>\n<p>SELECT * FROM Auftrag a INNER JOIN Auftragsposition pos on pos.AuftragID = a.AuftragID WHERE pos.Positionsfreitext like &#8218;Test%&#8216;<\/p>\n<p>Nat\u00fcrlich war auf der Auftragspositions-Tabelle ein Index auf Positionsfreitext. Ich erweiterte diesen Index um die AuftragID. Dadurch kann der Join direkt \u00fcber den Index abgewickelt werden und ein Zugriff auf die Tabelle wird eingespart, was f\u00fcr diesen Spezialfall ebenfalls eine deutliche Performance-Steigerung einbrachte.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In einem Kunden-Projekt sollte ich die Performance der SQL-Zugriffe einer .NET-Applikation verbessern. Hier beschreibe ich die Ergebnisse, da sie sich auch auf andere Szenarien verallgemeinern lassen. Die erste Ver\u00e4nderung war, keine GUIDs als clustered primary keys zu verwenden. Stattdessen setzen wir nun ints (mit Identity) ein. Dies f\u00fchrt zu einer immensen Beschleunigung bei den INSERTs &hellip; <a href=\"https:\/\/www.csopro.de\/biblog\/2009\/03\/performance-und-guids\/\" class=\"more-link\"><span class=\"screen-reader-text\">Performance und GUIDs<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[21,25],"class_list":["post-58","post","type-post","status-publish","format-standard","hentry","category-sqlserver","tag-guid","tag-performance"],"_links":{"self":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/58","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/comments?post=58"}],"version-history":[{"count":1,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/58\/revisions"}],"predecessor-version":[{"id":274,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/58\/revisions\/274"}],"wp:attachment":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/media?parent=58"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/categories?post=58"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/tags?post=58"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}