Vor- und Nachteile Überprüfen Sie, ob ein Wert für eine eindeutige Spalte vorhanden ist, oder lassen Sie db beim Einfügen einen eindeutigen Fehler auslösen
8
Als ich neulich eine Anfrage schrieb, kam mir ein Gedanke und ist mir in den Sinn gekommen.
Was ist vorzuziehen, indem Sie zuerst prüfen, ob ein Wert für eine eindeutige Spalte vorhanden ist, und dann einfügen oder einfügen und db einen eindeutigen Einschränkungsfehler auslösen lassen? Wird es überhaupt eine Rolle spielen?
Bearbeiten: Wie unten in der Antwort vorgeschlagen, dass dieses Problem von der Datenbank abhängt, füge ich das Tag postgresql hinzu.
Ich denke nicht, dass Ihre Frage wirklich datenbankunabhängig ist. Die richtige Antwort kann von Implementierungsdetails abhängen, die von Anbieter zu Anbieter variieren und sich mit der nächsten Version ändern können. Ich würde unter Parallelität testen, bevor ich einen Ansatz für ein RDBMS wähle.
Derzeit verwende ich unter SQL Server 2008 R2 Folgendes:
Geringe Parallelität und geringe Anzahl von Änderungen. Um eine einzelne Zeile zu speichern, serialisiere ich mit sp_getapplock und verwende MERGE. Ich mache einen Stresstest unter hoher Parallelität, um zu überprüfen, ob es funktioniert.
Höhere Parallelität und / oder Volumen. Um Parallelität zu vermeiden und die Leistung zu steigern, speichere ich nicht jeweils eine Zeile. Ich sammle Änderungen auf meinem App-Server und verwende TVPs, um Stapel zu speichern. Um Probleme im Zusammenhang mit der Parallelität zu vermeiden, serialisiere ich vor dem MERGE mit sp_getapplock. Wieder mache ich Stresstest unter hoher Parallelität, um zu überprüfen, ob es funktioniert.
Infolgedessen haben wir eine gute Leistung und keine Probleme mit der Parallelität in der Produktion: keine Deadlocks, keine Verstöße gegen PK / eindeutige Einschränkungen usw.
Sie wollen also sagen, dass es eine gute Idee ist, zuerst zu prüfen, ob Parallelitätsprobleme gut behandelt werden?
Codecool
1
Ja, normalerweise ist das Vermeiden von Fehlern besser als das Auslösen und Abfangen von Ausnahmen, aber Sie müssen es auf Ihrer Plattform vergleichen.
AK
7
Lassen Sie die DB einen Fehler auslösen.
Das erste Testen ist nicht sicher für die Parallelität, da Sie möglicherweise eine Kollision erhalten, da 2 Threads möglicherweise "NOT EXIST" bestehen und beide versuchen zu schreiben. Dies gilt sowohl für "READ COMMITTED" - als auch für MVCC / Snapshot-Sperrstrategien.
Sie können Sperrhinweise verwenden, um die Isolation zu erzwingen, aber Sie verringern die Leistung.
Ich denke, es ist nützlich, sowohl die Prüfung durchzuführen (als auch ordnungsgemäß zu scheitern), aber dem Sprichwort "Vertrauen, aber Verifizieren" zu folgen, um den Fehler zu erkennen. Der Grund? Fehlerbehandlung ist teuer. Ich arbeite heute an einigen Tests, die zeigen sollten, ob dieser Kommentar sinnvoll ist. Wenn dieser Kommentar verschwindet, kennen Sie das Ergebnis. :-)
Aaron Bertrand
Auch im Jahr 2008 gibt es MERGEmöglicherweise Beobachtungen von Paul gelöst, aber ich habe dies nicht bei hohen Sendequoten getestet. Meistens, weil ich mein Gehirn noch nicht trainiert habe, um diese Syntax zu verstehen.
Aaron Bertrand
1
Mea culpa. Ich habe heute einige Beobachtungen in meinen Tests gemacht. Beachten Sie, dass dies sehr isolierte Tests ohne Parallelität sind. Bei geraden Einsätzen ist die Überprüfung und Vermeidung des Fehlers etwa zehnmal schneller als das Auftreten des Fehlers. In anderen Fällen, in denen Sie eine komplexere Fehlerbehandlung durchführen (TRY / CATCH oder IF @@ ERROR <> 0, mit ROLLBACK oder THROW usw.), ist dies etwa doppelt so langsam, wenn Sie zuerst prüfen. Ich möchte noch einmal betonen, dass dies nur meine ersten Beobachtungen sind und dass es viele Faktoren gibt, die die Auswirkungen beeinflussen können, die sie haben können. Es kann einige Zeit dauern, bis ich gründlich darüber bloggen kann.
Lassen Sie die DB einen Fehler auslösen.
Das erste Testen ist nicht sicher für die Parallelität, da Sie möglicherweise eine Kollision erhalten, da 2 Threads möglicherweise "NOT EXIST" bestehen und beide versuchen zu schreiben. Dies gilt sowohl für "READ COMMITTED" - als auch für MVCC / Snapshot-Sperrstrategien.
Sie können Sperrhinweise verwenden, um die Isolation zu erzwingen, aber Sie verringern die Leistung.
Ich nenne das das JFDI-Muster (SO-Link). Informationen zu "Update falls vorhanden" finden Sie hier: Benötigen Sie Hilfe zur Fehlerbehebung beim SQL Server 2005-Deadlock-Szenario . Dies sind SQL Server. MySQL hat INSERT IGNORE, das dies ordnungsgemäß handhabt. Ich bin mir nicht sicher über den Rest
quelle
MERGE
möglicherweise Beobachtungen von Paul gelöst, aber ich habe dies nicht bei hohen Sendequoten getestet. Meistens, weil ich mein Gehirn noch nicht trainiert habe, um diese Syntax zu verstehen.