Laden...

Immer mal wieder SQL Timeouts

8 Antworten
2,926 Aufrufe
Letzter Beitrag: vor 15 Jahren
Immer mal wieder SQL Timeouts

Hi Leute,

ich habe einen Windows Dienst geschrieben welcher in regelmäßigen Intervallen Daten ließt, konvertiert und dann in eine SQL Datenbank schreibt. Dabei tritt es immer mal wieder auf, dass ich Timeouts erhalte. das Problem dabei ist, dass inzwischen eine solche Datenmenge übertragen wird, dass die Statements einfach eine gewisse Zeit brauchen. Ich habe Sie inzwischen schon optimiert und alles. Bei mir auf meinem Testsystem funktioniert auch alles einwandfrei auch mit großen Datenmengen. Sobald ich das ganze aber auf dem Server einspiele bekomme ich immer wieder Timeout Exceptions vom SQl Server. das ist natürlich ziemlich blöd und ich weis nicht was ich noch verändern kann.

Timeouts am SQL Server hochsetzen? Ist das Sinnvoll?

Es gibt zum Beispiel ein Update Statment, welches ich nachdem ich die Daten in die Tabelle eingefügt habe rüber laufen lasse. dieses Statement macht nichts weiter als einen Feldinhalt je Zeile zu setzen. Also es sieht so aus:

Update AP_Plan set Key_View = '050-' + Key_Number where (Key_View is null);

Da ich je Intervall um die 10.000 Datensätze in diese Tabelle importiere werden auch genausoviel Datensätze aktualisiert. Führe ich das Statement auf dem Server direkt aus dauert es um die 1,5 Sekunden. Da ich das Statement aber von einem anderen Server aus ausführe, dauert es teilweise 32 Sekunden. Das Netzwerk ist sonst super schnell, ich habe keine Ahnung, warum das so lange dauert.

Vielleicht hat diese Frage hier auch nichts zu suchen, aber ich weis nicht wo hin sonst damit.

Vielen Dank für jede Idee die Ihr habt.

LG Loewchen

Hallo Loewchen

Dein Timeout hört sich nicht nach einem "Server-Timeout" an sondern nach einem "Command-Timeout". Das ist standardmäßig auf 30 Sekunden. Setze auf deinem SqlCommand die CommandTimeout Property auf 0, damit läuft das Command solange wie's eben braucht.

Bei sehr großen Datenmengen sollte man außerdem in Batches arbeiten, also Blöcke über "UPDATE TOP(xyz)" verarbeiten. Allerdings fällt 10,000 da definitiv nicht drunter - wenn der SQL Server auf halbwegs ordentlicher Hardware arbeitet.

Der Netzwerktraffic ist eigentlich auch kein Problem wenn du wirklich das von dir gezeigte UPDATE ausführst. Die Daten werden komplett auf dem Server aktualisiert, da kommt nichts zum Client und wieder zurück.

Führst du wirklich nur ein einziges UPDATE aus welches dann über 30 Sekunden dauert oder führst du viele einzelne Statements aus?

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Hi Flo,

Das war nur ein Beispiel.
Ich hole mir Daten vom Server zum Client, speicher Sie dann in einem Dataset. Das bearbeite ich dann solange, bis es meinen "Wunschvorstellungen" entspricht, das schreibe ich dann zurück. Dabei habe ich ein "einfaches" Select Statement wie

Select Spalte1. Spalte2, Spalte3, Spalte4 ... from Tabelle1.

Ich arbeite noch nicht mit SQLinq in diesem Windows Dienst. Das gab es damals noch nicht als ich den Dienst geschrieben habe. Ich arbeite mit SQLCommand & Co. Alles was halt dazugehört.

Nachdem ich die Daten rüber geschoben habe, gehe ich dann halt nochmal mit Update Statements rüber wie zum Beispiel das von mir am Anfang geschriebene. Ich weis, es ist nicht schick, aber halt auch historisch gewachsen. Solche Statments schicke ich dann nacheinander mehrere rüber. Meiner Meinung nach, sollte das auch alles zu lasten des Servers gehen und nichts mit der Leitung zu tun haben und die IT sagt, dass der Server nicht ausgelastet ist.

Stimmt auch, die CPU Last geht auf maximal 50% Auslastung hoch, was aber auch daran liegen kann, dass es ein 2 Prozessor System ist und nicht beide mit einbezogen werden. Alles nicht so schön. An der Datenmenge sollte es eigentlich auch nicht liegen. Tja. Ich habe keine Idee, wie ich das sonst beschleunigen soll. Aber die Command Timeouts kann ich hochsetzen. Hauptsache ich lege den Server nicht Lahm 😉

Für weitere Ideen stehe ich jederzeit offen, so lange ich nicht mein Programm komplett umstricken soll.

Hi

Ich arbeite noch nicht mit SQLinq

Würde ich auch fast von abraten in deinem Fall. Wenn du mit ADO.NET schon an der Performance arbeiten musst macht's ein ORM auf keinen Fall besser.

T sagt, dass der Server nicht ausgelastet ist. ... Stimmt auch, die CPU Last geht auf maximal 50% Auslastung hoch, was aber auch daran liegen kann, dass es ein 2 Prozessor System ist und nicht beide mit einbezogen werden.

Das heißt nix. CPU ist nicht alles. Wenn die Kiste IO-mäßig am Limit läuft oder der SQL Server viel im RAM swappen muss hat die CPU keine Chance. Wenn ihr SQL Server 2005 oder 2008 habt werden (wenn nicht explizit ausgeschalten) auch für einzelne Statements beide CPUs verwendet - wenn sich's lohnt.

Mir sind noch ein paar Gründe eingefallen die bei den Updates eventuell zu hoher Last führen können:
* Aktualisierst du eventuell PK-/FK-Spalten? Wenn ja, dann kann ein kaskadierendes Update natürlich schnell einen n-fachen Aufwand erzeugen.
* Ein anderer Grund könnten noch große Daten (VARCHAR(MAX), TEXT, IMAGE, VARBINARY(MAX), ...) sein.
* Kann es sein dass einfach ein Index fehlt und der Full-Table-Scan so lange dauert?

Funktioniert's denn mit dem hochgesetzten CommandTimeout? Wenn ja, wirf parallel mal den SQL Server Profiler an und schau dir den Ressourcen-Verbrauch an.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

Transaction nicht vergessen.

Den Tiemout habe ich hochgesetzt. Schmeiße den Profiler gleich mit an, das ist eine gute Idee und dann lass ich das ganze mal unangetastet laufen. Wenn er fertig ist werte ich die Ergebnisse aus. Hoffe das bringt es.

Heißt dass, das SQLLinq nicht zu empfehlen ist für Massentransaktionen?

Meine update Statements beziehen sich lediglich auf Textspalten (varchar(50) (manchmal auch 255)) und es werden aus zwei beteits vorhanden Spalten, ebenfalls varchar, die Texte miteinander verknüpft. Hat was mit der Anzeige in der GUI zu tun. Es fehlt auch kein Index.

@FZelle:
Transaction nicht vergessen? Kannst Du mir mal auf die Sprünge helfen? Weis nicht worauf Du hinaus willst.

Heißt dass, das SQLLinq nicht zu empfehlen ist für Massentransaktionen?

Meine update Statements beziehen sich lediglich auf Textspalten (varchar(50) (manchmal auch 255)) und es werden aus zwei beteits vorhanden Spalten, ebenfalls varchar, die Texte miteinander verknüpft. Hat was mit der Anzeige in der GUI zu tun.

Mit LINQ2SQL kannst du, ohne selbst wieder SQL einzubauen, kein UPDATE über mehrere Zeilen abschicken. O/R-Mapper arbeiten Zeilen (Objekt) basiert. Damit sehe ich in deinem Fall keinen wirklichen Vorteil.

@FZelle:
Transaction nicht vergessen? Kannst Du mir mal auf die Sprünge helfen? Weis nicht worauf Du hinaus willst.

Was FZelle hier meint ist:
Wenn du viele einzelne Statements (also SqlCommands) auf die Datenbank abschickst solltest du unbedingt mit Transaktionen arbeiten. Das bringt zum einen oft einen massiven Performance-Vorteil, zum anderen ist es schlicht korrekt, da eine auszuführende Aktion entweder ganz oder gar nicht ausgeführt werden sollte. Schau dir hierzu mal SqlConnection.BeginTransation(), SqlTransaction und SqlCommand.Transaction an.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

@Loewchen0507:
Du bist jetzt seit 6 Monaten mit den Timeouts bei deinem Sql Server beschäftigt.
Und immernoch siehst Du es nicht ein, dich mit den Grundlagen zu beschäftigen?

SQL Abfrage und Timeout

Das macht es für dich nicht wirklich einfacher.
Komm mir jetzt nicht wieder mit dem Argument du hättest keine Zeit.
Du verplemperst ständig deine und unsere Zeit, weil du es nicht machst.