2016-03-27 4 views
1

Ich versuche, meine Abfrageausführungszeit zu optimieren Verwenden Lowest Lock-Ebene (Rowlock) aber es wird nicht wirksam "höhere Lock-Ebene (IX) gewährt" bei der Ablaufverfolgung in SQL Profiler,SQL Server-Sperrhinweis in Einfügung Anweisung erteilt die angegebene Sperre nicht

Mein Szenario:

  • vorausgesetzt, ich habe zwei Tabellen dbo.Students und dbo.University
  • dbo.Students hat eine Fremdschlüsselspalte zur University Tabelle

Abfrage

INSERT INTO dbo.Students WITH (ROWLOCK) (UniversityId, StudentName) 

Wenn Trace Locks in SQL-Profil

  • Student Tabelle gewährt IX (Intent Exclusive)
  • University Tabelle gewährt sch_s (Schema Stabilisierung)

und Dort werden viele Page- und Key-Locks erteilt und vor Freigabe freigegeben singe diese zwei Schlösser.

Kann jemand mir helfen, Reihensperren nur in der Kursteilnehmertabelle zu gewähren?

+0

Sie erhalten Sperren auf referenzierte Tabelle, wenn Sie den FK fallen lassen.Wie sollte der Server die Datenintegrität prüfen, ohne diese Prüfung durchzuführen (d. H. Nach der entsprechenden Zeile in der referenzierten Tabelle zu suchen)? Sind Sie sicher, dass hier etwas zu optimieren ist? Vielleicht sollten Sie die Anzahl der Indizes, die Trigger und die Länge der gesamten Transaktion betrachten, wenn dies nicht die einzige Operation ist? –

+0

Ich bin mir nicht sicher, aber ich dachte, ich kann die Sperre Ebene von IX (Intent exklusiv) auf die gesamte Tabelle zu reduzieren To RowX (Exklusiv nur in Zeile) Ich versuchte, die Identität aus der Primärschlüsselspalte zu entfernen, aber es gewährte weiterhin Sperre auf die ganze Tabelle @IvanStarostin –

+0

Diese Sperren sind absolut korrekt - sie sagen zu anderen Transaktionen, dass sie nicht ausschließlich ganze Tabelle oder Seite sperren können (wo die gesperrte Zeile liegt), weil ein Teil davon bereits jetzt gesperrt ist. IX-Sperren beschleunigen die Überprüfung auf das Vorhandensein solcher untergeordneten Sperren. Andernfalls müsste der Server jede Zeile konsequent überprüfen. Und alles was du sagst, sieht immer noch wie eine vorzeitige Optimierung aus. Wenn Ihre Auswahl aus irgendeinem Grund gesperrt bleibt, optimieren Sie Ihre Auswahl. Dies ist eine atomare Einfügung (wenn es keine Trigger oder etwas gibt). Sind Sie sicher, dass Sie einen Grund haben, es zu "optimieren"? –

Antwort

1

Beschreibung des Verhaltens

Sehr wahrscheinlich gibt es eine FOREIGN KEY Constraint zwischen diesen beiden auf dbo.Students Tabelle definierten Tabellen so:

ALTER TABLE dbo.Students 
... 
[ADD CONSTRAINT constraint_name] 
FOREIGN KEY (UniversityId) 
REFERENCES dbo.University (UniversityId) 

Sehr wahrscheinlich, diese Einschränkung aktiviert ist (siehe sys.foreign_keys.is_disabled) und SQL Server ist "forciert", um diese Integritätsbedingung zu überprüfen: , wenn jemand eine Zeile in dbo.Students mit nicht null @UniversityId einfügen Es prüft, ob uid bereits in dbo.University.UniversityId Spalte existiert. Das bedeutet, dass SQL Server einige Schlüssel/Datensätze aus dem eindeutigen Index, der der Spalte dbo.University.UniversityId zugeordnet ist, sperren muss (ein Fremdschlüssel muss auf eine oder mehrere Spalten verweisen, die der Schlüssel eines eindeutigen Indexes sind). Hinweis: Soweit ich mich an einen Kommentar von einem ehemaligen Mitglied des SQL Server-Entwicklungsteams erinnere, verwendet SQL Server die Isolationsstufe Serializable für solche Überprüfungen (ich habe keine Referenzen für diese Informationen).

Frage

Kann mir jemand helfen Zeilensperren nur in der Studenten-Tabelle zu gewähren?

"Solution" (nicht)

Grundsätzlich möchte man auf dbo.University Tabelle zu vermeiden, sperren. Es gibt eine Lösung (ungetestet): Aufhebung der Fremdschlüsseleinschränkung, aber es wird NICHT EMPFOHLEN.

+0

danke @Bogdan Sahlean dies kurz demonstrieren Sperren auf die referenzierte Tabelle, aber was ist mit Sperren auf der Haupttabelle (kann t Zeilensperre gesenkt werden) –

+0

@MosabMelhim: Die erste Überprüfung würde ich tun um zu sehen, ob 'sys.indexes.allow_row_locks' 1 oder 0 ist. –