2012-03-27 4 views
4

Ich bin in der mehrjährigen Situation: eine Abfrage, die sofort durch SSMS mit einer Handvoll Lesevorgänge ausgeführt wird, aber langsam genug, um mit Tausenden von Lesevorgängen auszusetzen über ADO.NET. Im Gegensatz zu die anderen Fragen, die ich auf StackOverflow finden konnte, den Query-Cache zu löschen (oder mich zwingen, den einen SSMS zu verwenden) scheint nicht den Trick zu tun.XML-basierte Abfrage extrem langsam durch ADO.NET, sofort durch SSMS

Wenn andere diese Situation in StackOverflow gemeldet haben, haben sie im Allgemeinen korrupte Abfrage-Caches. In allen diesen Fällen wurden entweder die ADO.NET-Abfragen mit SET ARITHABORT ON ausgeführt (um den von SSMS verwendeten Sitzungseinstellungen zu entsprechen) oder DBCC DROPCLEANBUFFERS und DBCC FREEPROCCACHE ausgeführt, um die Neuerstellung des Abfragecaches zu erzwingen. Diese Techniken machen keinen Unterschied in meiner Anwendung und lassen mich glauben, dass etwas Grundlegenderes passiert.

Die Abfrage in Frage ist (tatsächlich wörtlich Abfrage von SQL Profiler erfasst, nur für die Formatierung bereinigt):

declare @p5 xml 
set @p5=convert(xml,N'<r> 
<n v="66ebc21b3bcb31e9a5ecbfb4b29fd2a47c37994c"/> 
<n v="665919306fb23d9e685638a2d199e1e623745305"/> 
<n v="a080c3b4e0c86e37b4d494d5efc09cebe20c6929"/> 
<n v="245cb49bdeca9e37ef9bbd55877e21ade14e6282"/> 
<n v="297650a6be65be332c1bb2aab426331a156ee342"/> 
<n v="6a2668c8ab64fecf3b6925c7be613c61cef4dd7c"/> 
<n v="09923f25f8b1de19f693bca1111bfa50d617856e"/> 
<n v="0a7836d8e4e34f4ea92b2105eea5a99029949428"/></r>') 
exec sp_executesql N' 
      SELECT ixChangesetTag, ixRepo, ixChangeset, sTag, fBookmark 
      FROM ChangesetTag 
       INNER JOIN @p2.nodes(''/r/n'') X(n) ON X.n.value(''xs:hexBinary(@v)'', ''binary(20)'') = ixChangeset 
      WHERE ixRepo = @p0 AND ixCustomer = @p1',N'@p0 bigint,@p1 int,@p2 xml',@p0=2,@p1=23363,@[email protected] 

(Der XML-Parameter ist, um mit einer parametrisierte Abfrage, wo zu erlauben würde ich Normalerweise haben Sie Probleme damit, da die Anzahl der Objekte, die ich übergeben möchte, unterschiedlich ist.Tabellenwerte Verfahren wäre der 2008 Weg, dies zu tun, aber einige unserer Kunden laufen im Jahr 2005.

Durchlaufen SSMS, die Der tatsächliche Abfrageplan, der verwendet wird, sieht angemessen aus (Index sucht) und benötigt ungefähr 200 Lesevorgänge über 4 ms. Wenn Sie die Webanwendung durchlaufen, dauert es etwa 4500 Mal mehr als eine Sekunde.

Was fehlt mir hier? Könnte etwas den fehlerhaften Abfrageplan wiederherstellen, wenn er trotz der DBCC Anrufe und ARITHABORT Einstellungen über die Webanwendung ausgeführt wird?

+0

"es ist eine typische Verwendung-XML-to-do-a-parametrisierte WHERE IN-Klausel hack" - führen Sie das von mir wieder? –

+0

BTW: "In allen diesen Fällen führte die Fehlerbehebung entweder die ADO.NET-Abfragen mit SET ARITHABORT ON durch (um die von SSMS verwendeten Sitzungseinstellungen anzupassen) oder DBCC DROPCLEANBUFFERS und DBCC FREEPROCCACHE, um den Abfragecache zu erzwingen um zu rekonstruieren "- keiner von denen sind eigentlich Fixes. Das ist die Behandlung der Symptome und nicht die eigentliche Ursache. –

+0

@MitchWheat Ich räumte diese Erklärung ein bisschen auf. Diese Abfrage ersetzte eine durch eine beliebige, potentiell große Anzahl von Elementen in einer Klausel 'WHERE ixChangeset IN (...) ', wodurch sie parametrisiert werden konnte und den Abfragecache traf. –

Antwort

1

Das Problem endete damit, dass SQL Server im Allgemeinen eine absolut schreckliche Ausführungsstrategie auswählte, im Grunde die XML wiederholt wiederholt, anstatt eine vernünftige Verbindung zu machen. Die Lösung bestand darin, das XML in eine temporäre Tabelle zu stellen und stattdessen , beizutreten, was zu guten Ausführungsplänen führte.

1

Einfache Lösung wäre, einen mehrspaltigen Index anzulegen (ixCustomer, ixRepo, ixChangeset). Ohne zu wissen, was die Spalten tatsächlich sind, ob sie einzigartig sind usw. ist es schwierig, eine bessere Antwort zu finden.

+0

Da die Abfrage bei der Ausführung von SSMS sofort ausgeführt wird, möchte ich nicht glauben, dass dies ein Indexproblem ist. –

+0

@Benjamin Pollack - Wenn Sie von SMS laufen, wählt es einen besseren Index dann, wenn Sie von Code ausführen, wahrscheinlich zu einigen mehrdeutigen Zeichensatzeinstellung oder etwas tun. NET anders als die Standard-SMS-Sitzung. Wenn Sie den mehrspaltigen Index machen, wird er immer dazu neigen, ihn zu benutzen. –

Verwandte Themen