Frage

Ich habe eine gespeicherte Prozedur, die als viel schneller von SQL Server Management Studio (2 Sekunden) führt bei der Ausführung mit System.Data.SqlClient.SqlCommand (Timeout nach 2 Minuten).

Was ist der Grund dafür sein könnte?


Details: In SQL Server Management Studio läuft dies in 2 Sekunden (auf Produktionsdatenbank):

EXEC sp_Stat
    @DepartmentID = NULL

In .NET / C # die folgenden Zeiten aus nach 2 Minuten (auf Produktionsdatenbank):

string selectCommand = @"
EXEC sp_Stat
    @DepartmentID = NULL";
string connectionString = "server=***;database=***;user id=***;pwd=***";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (SqlCommand command = new SqlCommand(selectCommand, connection))
    {
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
            }
        }
    }
}

Ich habe auch versucht mit selectCommand = "sp_Stat", CommandType = StoredProcedure und einem SqlParameter, aber es ist das gleiche Ergebnis.

Und ohne EXEC es ist das gleiche Ergebnis auch.

Auf einer fast Daten leere Entwicklung Datenbank beiden Fälle in weniger als 1 Sekunde beendet. So ist es im Zusammenhang mit, dass eine Menge von Daten in der Datenbank gibt es, aber es scheint nur zu passieren, von .NET ...


Was Marc GRA schrieb über verschiedene SET Werte macht den Unterschied im vorliegenden Fall.

SQL Server Profiler zeigte, dass SQL Server Management Studio führt die folgenden SET ist, dass .NET SQL-Client-Datenprovider nicht:


SET ROWCOUNT 0 
SET TEXTSIZE 2147483647 
SET NOCOUNT OFF 
SET CONCAT_NULL_YIELDS_NULL ON 
SET ARITHABORT ON 
SET LOCK_TIMEOUT -1 
SET QUERY_GOVERNOR_COST_LIMIT 0 
SET DEADLOCK_PRIORITY NORMAL 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
SET ANSI_NULLS ON 
SET ANSI_NULL_DFLT_ON ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET CURSOR_CLOSE_ON_COMMIT OFF 
SET IMPLICIT_TRANSACTIONS OFF 
SET QUOTED_IDENTIFIER ON
SET NOEXEC, PARSEONLY, FMTONLY OFF

Als ich diese enthalten, nahm die gleiche Abfrage, um die gleiche Menge an Zeit in SSMS und .NET. Und der verantwortliche SET ist ...

SET ARITHABORT ON

Was habe ich gelernt? Vielleicht einen Profiler zu verwenden, anstatt zu raten ...

(Die Lösung schien zunächst verwandt zu sein Schnüffeln auf den Parameter. Aber ich hatte ein paar Dinge durcheinander ...)

War es hilfreich?

Lösung

Eine andere Sache, die wichtig sein kann, ist der SET Optionen , die aktiviert. Einige dieser Optionen ändern, um den Abfrage-Plan ausreichend um das Profil zu ändern. Einige können einen großen Einfluss haben, wenn Sie betrachten (zum Beispiel) ein berechneter + anhielt (und möglicherweise indiziert) Spalte: Wenn die SET Optionen nicht kompatibel sind, können sie die Werte neu zu berechnen gezwungen werden, anstatt die indexierten Wert -., die einen Index sucht in eine Tabelle Scan + Berechnung ändern

Versuchen Sie, den Profiler zu sehen, was SET Optionen „im Spiel“ sind, und sehen, ob diese Optionen Dinge ändert.

Eine weitere Auswirkung ist die Verbindungszeichenfolge; zum Beispiel, wenn Sie MARS ermöglichen, dass das Verhalten auf subtile Weise ändern kann.

Schließlich Transaktionen (implizite (TransactionScope) oder explizit) können eine haben große Auswirkungen, abhängig von der Isolationsstufe.

Andere Tipps

Dies ist fast sicher aufgrund eines ‚falschen‘ im Cache Abfrage-Plan. Dies hat auf SO ein paar Mal recht kommen.

Haben Sie up-to-date Statistiken haben? Eine planmässige Index Wartungsplan?

Sie können testen, ob es durch das Hinzufügen dieser zu Ihrer gespeicherten Prozedur Definition auf jeden Fall aufgrund der zwischengespeicherten Abfrageplan ist:

CREATE PROCEDURE usp_MyProcedure WITH RECOMPILE...

Das wird eine komplette Datenbank neu indiziert (Vorsicht, wenn Datenbank sehr groß ist!):

exec sp_msforeachtable "dbcc dbreindex('?')"

SO-Beiträge:

Großer Unterschied in Ausführungszeit des gespeicherten proc zwischen Managment Studio und Tableadapter.

Parameter Sniffing (oder Spoofing) in SQL Server

für unbekannte für SQL Server 2005 optimieren?

Unterschiedliche Ausführungsplan für den gleichen Stored Procedure

Sie hat ein ähnliches Problem und es stellt sich heraus, Multiple = true in der Verbindungszeichenfolge mit (der minimalen Auswirkungen haben sollte) machte 1.5mil Aufzeichnungen über eine Remoteverbindung nimmt 25 Minuten statt ca. 2 Minuten ziehen.

Wir hatten ein ähnliches Problem, wo eine Abfrage in 2 Sekunden in SSMS abschließen würde und mehr als 90 Sekunden in Anspruch nehmen, wenn sie von einem .NET-Client aufgerufen (wir mehr VB / C # apps / Websites geschrieben, es zu testen.)

Wir vermuteten, dass der Abfrage-Plan anders sein würde, und schrieben die Abfrage mit expliziter Schleife ( „innere Schleife verbinden“ und „mit dem Index“) Hinweise. Dies löste das Problem.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top