2009-04-20 12 views
3

Ich habe eine SqlDataAdapter, die mit 21 Zeilen von Daten (4 Spalten) gefüllt wird. Der Sproc, der es antreibt, kehrt in SQL Mgmt Studio in ein paar Sekunden zurück, aber das .Fill() dauert 5 Minuten.SqlDataAdapter.Fill() Timeout - zugrunde liegenden Sproc zurückgegeben schnell

ArrayList ret = new ArrayList(); 
    SqlDataAdapter da = null; 
    SqlCommand cmd = null; 
     cmd = base.GetStoredProc("usp_dsp_Stuff"); //Returns immediately in MSSMS. 
     cmd.CommandTimeout = 3600; // Set to 6 min - debug only 
     base.AddParameter(ref cmd, "@Param1", ParameterDirection.Input, SqlDbType.BigInt, 8, 19, 0, theParam1); 
     base.AddParameter(ref cmd, "@Param2", ParameterDirection.Input, SqlDbType.BigInt, 8, 19, 0, theParam2); 
     base.AddParameter(ref cmd, "@Param3", ParameterDirection.Input, SqlDbType.Char, 1, 'C'); 
     da = new SqlDataAdapter(cmd); 
     DataTable dt = new DataTable(); 
     da.Fill(dt); //Takes 5 minutes. 

Irgendwelche Ideen?

Vielen Dank im Voraus! -Chris

Antwort

0

Fill() kann manchmal langsam sein, da .NET die Daten analysiert, die von der Prozedur zurückkommen.

Verwenden Sie den SQL Profiler, um herauszufinden, was SQL .NET tatsächlich sendet, wenn Fill() ausgeführt wird.

Wenn es eine Menge von SET-Anweisungen zu senden, wie

 
set concat_null_yields_null on 
set cursor_close_on_commit off 
set implicit_transactions off 

etc... 

.. dann die gleiche Satz Anweisungen in der gespeicherten Prozedur setzt kann Dinge zu beschleunigen.

2

Vielen Dank für die Hilfe. Die Lösung hierfür war mit (nolock) Anweisungen hinzufügen auf die Verbindungen, dass die sproc Verwendung wurde:

VON category_tbl c INNER JOIN dbo.categoryItem_LNK cl MIT (NOLOCK) ON c.categoryid = cl.categoryid

Ich weiß nicht, warum wir bei Verwendung des SqlDataAdapter nur eine Verschlechterung feststellen konnten, aber das hat das Problem sofort gelöst.

Nochmals vielen Dank, Chris

+0

das auch für mich gearbeitet, ich war aus noch eine Zeit bekommen nach 10 Sätze aus der Tabelle bewertet Funktion ziehen. – Sergey

+0

Ich hatte das gleiche Problem beim Ausführen einer Abfrage, aber die Verwendung von "WITH (NOLOCK)" hat nicht geholfen. Das Hinzufügen von "OPTION (RECOMPILE)" am Ende meiner Abfrage behebt das Problem. – sharpguru

1

Ich hasse die Nachricht zu brechen, aber (NOLOCK) ist keine Lösung, es schafft nur new problems, wie schmutzig liest,/duplizierten Daten fehlen, und sogar abgebrochene Abfragen. Sperren in einer SQL-Datenbank sind dein Freund.

Wenn das Sperren (oder schlechteres Blockieren) dazu führte, dass es langsam ist, vergleichen Sie die Verbindungsoptionen, die über SSMS laufen, und die von Ihrer Anwendung verwendeten. Verwenden Sie SQL Profiler, um zu sehen, wie der Code ausgeführt wird.

Wenn eines dieser Felder große Objekte sind, beachten Sie, dass SSMS standardmäßig nur einige hundert Zeichen automatisch abruft. Die zusätzlichen Daten könnten ein Faktor sein.

+0

In Wirklichkeit hängt es vom Anwendungsfall ab. Vielleicht könnten Sie erweitern "es schafft nur ein neues Problem", um dem Leser zu helfen zu entscheiden, ob diese Probleme ernst genug sind, um Bedenken für ihren eigenen Anwendungsfall zu verursachen. – Dan

0

Fehlerhafte Abfragepläne und Parameter-Sniffing. Bei einem gespeicherten Proc, und insbesondere bei einem, bei dem Parameter die gelesenen Zeilen stark verändern, ist ein fehlerhafter Ausführungsplan, der auf eingehende Parameter schaut, die Ursache. In SQL Management Studio kommt es aufgrund unterschiedlicher SET-Parameter nicht vor.

Dieser Thread fasst das Problem schön up: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/9fd72536-f714-422a-b4c9-078e2ef365da/

Dies ist ein typischer Fall von Parametern Sniffing. Ihre Anwendung höchstwahrscheinlich läuft mit anderen SET-Optionen (Set von der Client-API) und verwendet einen anderen Ausführungsplan als die in SSMS erstellt . Was passiert ist, wenn Ihre Prozedur die erste Zeit über Ihre Anwendung aufruft, erstellt Ausführungsplan basierend auf den Parametern übergeben.Dieser Ausführungsplan ist jedoch möglicherweise nicht für einen anderen Parametersatz geeignet, was zu einer schlechten Leistung führen kann, wenn er mit dem anderen Parametersatz ausgeführt wird. Siehe folgenden für weitere Details und verschiedene Lösungen: http://pratchev.blogspot.com/2007/08/parameter-sniffing.html

Hier ist mehr auf die Interna von Plan-Caching und Abfrage-Plan Wiederverwendung:
http://technet.microsoft.com/en-us/library/cc966425.aspx

3

Ich weiß, das zu spät ist, wie 7 Jahre zu spät! Aber ich bin heute auf dieses Problem gestoßen und wollte meine Lösung teilen. In meinem Fall waren die Daten, die aus SQL gezogen wurden, eine Tabellenwertfunktion. Die Tabellenwertfunktion gab nur ungefähr 3500 Zeilen zurück und dauerte weniger als 1 Sekunde, aber es war ein Timeout für die Fill() im C# -Code. Ich weiß nicht, wer oder wie es funktioniert, aber fallenlassen und neu erstellen die Funktion repariert es. Ich denke, dass es etwas damit zu tun hat, wie .NET Daten liest, die von SQL gegeben werden, wie die Art, wie eine Ansicht neu erstellt werden muss, wenn Sie Änderungen daran vornehmen, nachdem sie in einem Bericht verwendet wurden. i wieder; m nicht 100% sicher, was hinter den Kulissen passiert, aber für mich war es eine schnelle Lösung

+0

Das hat es für mich gelöst. Hatte einen Funktionsaufruf am Anfang meiner SP, der 'floors' und 'ceilings' Datumsparameter. Ich entfernte die Funktion und machte den "Boden" und die "Decke" manuell, und es funktionierte. –

+0

Es stellt sich heraus, dass einfach das Ablegen und Wiederherstellen der gespeicherten Prozedur in unserem Fall dieses genaue Problem behoben. Nur für eine sichere Maßnahme haben wir sichergestellt, dass (NOLOCK) überall enthalten war. SQL Server Buggy jetzt - Am besten zu verwenden MongoDB – sean2078

1
da = new SqlDataAdapter(cmd); 
da.SelectCommand.CommandTimeout = 1800; 
+1

Bitte sehen Sie diese erste [how-to-answer] (https://stackoverflow.com/help/how-to-answer) –