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?
"es ist eine typische Verwendung-XML-to-do-a-parametrisierte WHERE IN-Klausel hack" - führen Sie das von mir wieder? –
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. –
@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. –