2009-05-14 11 views
2

Wir verwenden C# und Linq2SQL, um Daten aus einer Datenbank für einige Berichte zu erhalten. In einigen Fällen dauert dies eine Weile. Mehr als 30 Sekunden, das scheint der Standard CommandTimeout zu sein.C#, Linq2SQL: Wie lange sollte CommandTimeout sein und wo sollte es eingestellt werden?

Also, ich denke, ich muss die CommandTimeout. Aber die Frage ist, wie viel? Ist es schlecht, es sehr hoch zu setzen? Wäre es nicht schlecht, wenn ein Kunde versucht, etwas zu tun, und nur weil er viel mehr Daten in seiner Datenbank hatte als der durchschnittliche Kunde, der seine Berichte wegen Zeitüberschreitungen nicht bekommen konnte? Aber wie kann ich wissen, wie viel Zeit es möglicherweise dauern könnte? Gibt es eine Möglichkeit, es ins Unendliche zu setzen? Oder wird das als sehr schlecht angesehen?

Und wo soll ich es einstellen? Ich habe eine statische Datenbankklasse, die einen neuen Datenkontext für mich generiert, wenn ich ihn brauche. Kann ich einfach eine Konstante erstellen und einstellen, wenn ich einen neuen Datenkontext erzeuge? Oder sollte es je nach Anwendungsfall unterschiedliche Werte haben? Ist es schlecht, eine hohe Auszeit für etwas zu haben, das nicht viel Zeit in Anspruch nimmt? Oder ist es nicht wirklich wichtig?

Zu hoch ConnectionTimeout kann natürlich nerviger sein. Aber gibt es einen Fall, in dem ein Benutzer/Kunde eine Auszeit wünscht? Kann der SQL Server einfrieren, so dass ein Befehl niemals beendet wird?

Antwort

3

CommandTimeout usw. sollte in der Tat nur auf spezifischen Szenario-Basis erhöht werden. Dies kann unerwartet lange blockierende Szenarien vermeiden (oder schlimmer: das unentdeckte Deadlock-Szenario). Wie für wie high ... Wie lange dauert die Abfrage? Fügen Sie etwas Spielraum hinzu und Sie haben Ihre Antwort.

Die andere Sache ist natürlich, die Zeit zu reduzieren, die die Abfrage dauert. Dies könnte bedeuten, einige TSQL in einem Sproc manuell zu optimieren, normalerweise in Kombination mit der Überprüfung der Indexierungsstrategie und vielleicht größeren Änderungen wie Denormalisierung oder anderen Schemaänderungen. Dies kann auch eine Data-Warehousing-Strategie beinhalten, sodass Sie die Last in eine separate Datenbank verschieben können (weg von den Transaktionsdaten), wobei ein Schema für das Reporting optimiert ist. Vielleicht ein Sternenschema.

Ich würde es nicht ins Unendliche setzen ... Ich erwarte nicht, dass es ewig dauert, um einen Bericht zu erstellen. Wählen Sie eine Nummer, die für den Bericht sinnvoll ist.

Ja, SQL Server kann anhalten, damit ein Befehl nie beendet wird. Eine offene Sperrtransaktion wäre die einfachste ... bekomme zwei, und du kannst dich sperren. Normalerweise erkennt das System einen lokalen Deadlock - aber nicht immer, insbesondere wenn DTC involviert ist (d. H. Nicht lokale Sperren).

+0

Wie kann ich die Indexierungsstrategie überprüfen? Es gibt derzeit keine Indizes hinzugefügt, denke ich, aber wie kann ich sehen, wo ich sie hinzufügen sollte? (Sind Primärschlüssel bereits indiziert?) – Svish

0

IMHO, Eine erweiterte Option für Ihren Benutzer zum Festlegen des ConnectionTimeout-Werts wäre besser als jeder von Ihnen festgelegte konstante Wert.

0

Primärschlüssel verfügen standardmäßig über einen gruppierten Index. Ich fand das folgende Skript (ich glaube, es war auf msdn), die den Code generieren denkt jede Indizes SQL Server zu erstellen ist nützlich (def arbeitet auf SQL2008, ich denke, das im Jahr 2005 eingeführt wurde):

SELECT 

    migs.avg_total_user_cost * (migs.avg_user_impact/100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure, 

    'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle) 

    + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']' 

    + ' ON ' + mid.statement 

    + ' (' + ISNULL (mid.equality_columns,'') 

    + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END 

    + ISNULL (mid.inequality_columns, '') 

    + ')' 

    + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement, 

    migs.*, mid.database_id, mid.[object_id] 

FROM sys.dm_db_missing_index_groups mig 

INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle 

INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle 

WHERE migs.avg_total_user_cost * (migs.avg_user_impact/100.0) * (migs.user_seeks + migs.user_scans) > 10 

ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC 
+0

Glauben Sie, dass dies für etwas, das von Hand bearbeitet werden kann, zu viel ist? – Xander

0
//If you have an AseCommand object instance.... 
AseCommand _AseCommand = new AseCommand("procedure_test"); 

//You can set up the timeout infinite as follows 
_AseCommand.CommandTimeout = System.Threading.Timeout.Infinite; 
Verwandte Themen