{"id":265,"date":"2006-11-08T20:57:53","date_gmt":"2006-11-08T18:57:53","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/2006\/11\/08\/sql-talk\/indexes-am-sql-server-2005-nicht-alles-geht-online"},"modified":"2006-11-08T20:57:53","modified_gmt":"2006-11-08T18:57:53","slug":"indexes-am-sql-server-2005-nicht-alles-geht-online","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2006\/11\/08\/sql-talk\/indexes-am-sql-server-2005-nicht-alles-geht-online","title":{"rendered":"Indexes am SQL-Server-2005: nicht alles geht &quot;online&quot;"},"content":{"rendered":"<p>Durch die aktuelle Ausgabe des SQL-Server-Magazine wurde ich auf ein Problem aufmerksam: Wenn man LOBs (Large Objects) in einem Index speichert, dann kann man verschiedene Dinge nicht tun. Dazu reicht es schon, wenn das LOB-Feld nur auf der Index-Seite gespeichert ist, bspw. beim Clustered-Index.<\/p>\n<p><strong>online operations<\/strong><\/p>\n<p>Dazu steht in den &quot;<a href=\"http:\/\/msdn2.microsoft.com\/en-US\/library\/ms190981.aspx\">Guidelines for Performing Online Index Operations<\/a>&quot;:<\/p>\n<blockquote><p>When you perform online index operations, the following guidelines apply:<br \/>\nClustered indexes must be created, rebuilt, or dropped offline when the underlying table contains large object (LOB) data types: image, ntext, text, varchar(max), nvarchar(max), varbinary(max), and xml. <\/p><\/blockquote>\n<p>Kimberly L. Tripp beschreibt es in dem SQL-Server-Magazine-Artikel &quot;<a href=\"http:\/\/www.sqlmag.com\/Articles\/ArticleID\/93633\/93633.html\">Database Design for Performance<\/a>&quot; noch etwas genauer:<\/p>\n<blockquote><p>SQL Server 2005 allows any column to be in the leaf level of an index\u2014including LOB types. If a LOB type is in the leaf level of an index, the index won&#x0027;t support online operations.<\/p><\/blockquote>\n<p>Das gilt also auch f&#252;r Clustered-Indexes und betrifft im Wesentlichen &quot;ALTER INDEX REBUILD&quot;. Wenn es rechtzeitig vorher wei&#223;, dann sollte das kein Problem sein. Dann kann man n&#246;tigenfalls die Tabelle auf zwei aufteilen&#8230;<\/p>\n<p><strong>unerwartete Fehlermeldung<\/strong><\/p>\n<p>Meines Erachtens besteht aber auch ein Zusammenhang zu folgendem Ph&#228;nomen: In bestimmten F&#228;llen erscheint bei einem Update eine unerwartete Fehlermeldung:<\/p>\n<blockquote><p>The query processor could not produce a query plan from the optimizer because a query cannot update a text, ntext, or image column and a clustering key at the same time. <\/p><\/blockquote>\n<p>bzw. <\/p>\n<blockquote><p>Msg 8629, Level 16, State 3, Line 1 &#8211; Warnung: Der Abfrageprozessor konnte aus dem Optimierer keinen Abfrageplan erzeugen, da eine Abfrage nicht gleichzeitig eine text-, ntext- oder image-Spalte und einen Gruppierungsschl&#252;ssel aktualisieren kann. <\/p><\/blockquote>\n<p>Um bei einem UPDATE in das Problem zu laufen, m&#252;ssen folgende Bedingungen erf&#252;llt sein: <\/p>\n<ul>\n<li>Die Tabelle hat einen Clustered Index.<\/li>\n<li>Die Tabelle hat wenigstens ein Feld vom Typ IMAGE,  NTEXT, TEXT, NVarchar(max), Varchar(max), Binary(max) oder XML. <\/li>\n<li>Der Inhalt des Feldes wird nicht in dem Datensatz gespeichert. <\/li>\n<li>Der Zugriffsplan ist so ausgelegt, dass mehrere Datens&#228;tze ge&#228;ndert werden (selbst wenn tats&#228;chlich nur einer da ist). <\/li>\n<\/ul>\n<p><code lang=\"sql\">-- ggf. Testtabelle l&#246;schen<br \/>\nif object_id(&#x0027;tempdb..#t1&#x0027;) is not null<br \/>\n\tdrop table #t1<br \/>\ngo<br \/>\n&#8211; Testtabelle anlegen<br \/>\ncreate table #t1 (<br \/>\n\tc1 int not null,<br \/>\n\tc2 int not null,<br \/>\n\t\tprimary key clustered (c1,c2),<br \/>\n\tc3 text null,<br \/>\n\tc4 int identity)<br \/>\ngo<br \/>\n&#8211; Tabelle mit Testdaten f&#252;llen<br \/>\ninsert #t1 values (1,7,&#x0027;test&#x0027;)<br \/>\ngo<br \/>\n&#8211; Das geht problemlos:<br \/>\nupdate #t1 set c2=10, c3=&#x0027;test again&#x0027; where c2=7<br \/>\ngo<br \/>\n&#8211; Die Fehlermeldung verursachen:<br \/>\nupdate #t1 set c2=10, c3=replicate(&#x0027;x',8000)+replicate(&#x0027;y',8000) where c2=7 <\/p>\n<p>go<br \/>\n&#8211; ggf. Testtabelle l&#246;schen (aufr&#228;umen)<br \/>\nif object_id(&#x0027;tempdb..#t1&#x0027;) is not null<br \/>\n\tdrop table #t1<\/code><\/p>\n<div class=\"small\">aus den <a href=\"http:\/\/forums.microsoft.com\/TechNet\/ShowPost.aspx?PostID=678123&#038;SiteID=17\">TechNet-Foren<\/a><\/div>\n<p>Als Abhilfe kann ich zwei M&#246;glichkeiten anbieten:<\/p>\n<ol>\n<li>Den Custered Index entfernen oder in einen &quot;normalen&quot; Index &#228;ndern. <\/li>\n<li>Das Statement wird in zwei Einzelteile zerlegt: einen auf die LOB-Spalten und einen auf die anderen.<\/li>\n<\/ol>\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Durch die aktuelle Ausgabe des SQL-Server-Magazine wurde ich auf ein Problem aufmerksam: Wenn man LOBs (Large Objects) in einem Index speichert, dann kann man verschiedene Dinge nicht tun. Dazu reicht es schon, wenn das LOB-Feld nur auf der Index-Seite gespeichert ist, bspw. beim Clustered-Index. online operations Dazu steht in den &quot;Guidelines for Performing Online Index [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/265"}],"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=265"}],"version-history":[{"count":0,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/265\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=265"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}