Optionen zum Festlegen des NOLOCK-Hinweises in Dataset-Abfragen

7

Einige Zusammenhänge:
Zuerst haben wir Berichte nur "direkt" geschrieben, ohne irgendwelche Sperrhinweise in den Abfragen. Bei den größeren Berichten führte dies manchmal zu Sperrproblemen. Am ersten behoben wir dies durch die Verwendung WITH (NOLOCK)Hinweis für Tabellen in der Abfrage.

Da (a) es ziemlich aufdringlich ist und (b) es leicht ist, den Hinweis für eine der Tabellen zu vergessen, sind wir zu einer zweiten Annäherungseinstellung TRANSACTION ISOLATION LEVELüber READ UNCOMMITTED(was in Ordnung ist) oben in der Abfrage jedes Datensatzes übergegangen.

Wie Sie vielleicht erraten haben, ist es immer noch leicht, den Hinweis für einen der Datensätze zu vergessen. Das führt also zu der Frage:


Frage: Welche Möglichkeiten gibt es, um NOLOCKHinweise zusammen mit Berichtsabfragen zu senden ?

PS. Ich weiß , das zu einem gewissen Grad ist ein XY-Problem (mit vielen meinen anderen Optionen für X, wie die Abfrage zu optimieren, nicht auf der operativen Datenbank Berichterstattung zu tun, etc), aber versucht , trotzdem dies eine berechtigte Frage auf mich selbst zu machen .


Optionen:
Hier sind die oben genannten Optionen mit zusätzlichen Optionen, auf die ich gespannt bin, ob sie funktionieren würden:

  1. Set WITH (NOLOCK)Hinweis für jede Tabelle. (aufdringlich, sehr leicht zu vergessen)
  2. Set Isolationsstufe READ UNCOMMITTEDfür die gesamte Abfrage. (immer noch leicht zu vergessen)
  3. Ist es möglich, dies auf Berichtsebene anzugeben ? Stellen Sie beispielsweise sicher, dass alle Dataset-Abfragen für einen Bericht ohne Sperren ausgeführt werden.
  4. Ist es möglich, dies auf einer anderen SSRS-Ebene anzugeben ? Stellen Sie dies beispielsweise für einen bestimmten Berichtsordner oder mithilfe einer Erweiterung ein?
  5. Ist es möglich, dies auf der Ebene der Datenquelle / Verbindungszeichenfolge anzugeben ? Haben z. B. alle relevanten Berichte eine bestimmte "No-Lock-Datenquelle" verwendet?
  6. Bezogen auf die vorherige Option: Vielleicht ist es möglich, einen Standard-Sperrhinweis für einen bestimmten "No-Lock-SQL-Benutzer" (den in der Verbindung verwendeten) anzugeben?
  7. ???

Welche Optionen sind realisierbar? Gibt es Optionen, die ich verpasst habe?

Jeroen
quelle
Das Problem, überall zu Nolocks zu gehen oder die Isolation so zu ändern, dass sie nicht festgeschrieben ist, ist ein Problem mit der Datenqualität. Sie erhalten nicht nur schmutzige Lesevorgänge, sondern können möglicherweise dieselben Daten zweimal zurückgeben oder Daten insgesamt übersehen. Es ist möglicherweise besser, sich Ihr Design anzusehen und festzustellen, ob es Zeit für eine separate Berichtsdatenbank ist. Siehe diese Frage
Mike Walsh
@ MikeWalsh Einverstanden. Darauf habe ich auch versucht, mich in dem Teil über das XY-Problem zu beziehen. Wenn Sie jedoch vorsichtig vorgehen, kann es hilfreich sein, zu wissen, wo und wann die Verwendung von Verriegelungshinweisen möglich ist.
Jeroen

Antworten:

5

Schnelle Antworten:

  1. Funktioniert, wie Sie bemerkt haben.
  2. Funktioniert, wie Sie bemerkt haben.
  3. Dies scheint nicht zu funktionieren. Ich habe keine Option ohne weiteres gesehen, und wenn diese Frage gestellt wird, wird immer wieder die Isolationsstufe in der gespeicherten Prozedur festgelegt .
  4. Das würde ich nicht glauben. SSRS befindet sich auf einer höheren Abstraktionsschicht als das Datenbankmodul. In gewissem Sinne ist es ihm also egal, wie hoch die Isolationsstufe ist. Schließlich können Sie in Ihren Berichten Nicht-RDBMS-Lösungen verwenden.
  5. Das funktioniert nicht. Sie können die Isolationsstufe in der Verbindungszeichenfolge nicht festlegen .
  6. Das könnte funktionieren. Sie können einen Anmeldetrigger erstellen .

Es gibt einige Optionen, die sinnvoll sind, wenn die Berichte optimiert sind und dennoch Probleme verursachen:

  1. Verwenden Sie Always On, wenn Sie über SQL 2012 verfügen. Sie könnten dann ein schreibgeschütztes Replikat haben, das Ihre SSRS-Berichte verwenden könnten.
  2. Verwenden Sie die Replikation: Snapshot, wenn Sie keine Echtzeit benötigen, und Transaktions-Snapshot, wenn Sie möchten, dass er nahezu in Echtzeit ist.
  3. Wenn Sie nicht über das Budget für Always On oder die Geduld verfügen, um mit der Replikation umzugehen, führen Sie die Replikation kostengünstig durch: Erstellen Sie ein berichtsfreundliches Schema (dh denormalisieren Sie die Tabellen und legen Sie sie in einem Format ab, das das Ausführen von Berichten erleichtert ) und verwenden Sie SSIS, um dieses Berichtsschema zu füttern. Dies funktioniert besser, wenn Ihre Endbenutzer mit "älteren" Daten leben können (z. B. stündliche Aktualisierung oder alle 5 Minuten). Der Nachteil ist, dass Sie das Datenmodell zweimal entwerfen: einmal für das OLTP-Modell und einmal für das Pseudo-Warehousing-Modell. Der Vorteil ist, dass dies eine sehr hilfreiche Übung ist, wenn Sie sich jemals in Richtung eines zentralen Data Warehouse bewegen.
Kevin Feasel
quelle
6

Haben Sie über eine READ_COMMITTED_SNAPSHOTZeilenversionierung für die Datenbank nachgedacht ?

Kim Tripp hat einen guten Artikel darüber unter http://msdn.microsoft.com/en-us/library/ms345124%28v=sql.90%29.aspx

READ_COMMITTED_SNAPSHOTErmöglicht eine bessere Funktionalität als dies WITH (NOLOCK), da es eine absolute Zeitpunktkonsistenz für lang laufende Aggregationen oder Abfragen mit erhöhtem Durchsatz bietet, da weniger Sperrenkonflikte auftreten.

Max Vernon
quelle