Ich habe eine Reihe von Zeilen, die ich in die Tabelle einfügen muss, aber diese Einfügungen erfolgen immer stapelweise. Ich möchte also überprüfen, ob eine einzelne Zeile aus dem Stapel in der Tabelle vorhanden ist, da ich dann weiß, dass alle eingefügt wurden.
Es ist also keine Primärschlüsselprüfung, sollte aber nicht zu wichtig sein. Ich möchte nur eine einzelne Zeile überprüfen, also ist es count(*)
wahrscheinlich nicht gut, also ist es so etwas wie exists
ich denke.
Aber da ich ziemlich neu in PostgreSQL bin, würde ich lieber Leute fragen, die es wissen.
Mein Stapel enthält Zeilen mit folgender Struktur:
userid | rightid | remaining_count
Wenn die Tabelle also Zeilen enthält userid
, bedeutet dies, dass alle dort vorhanden sind.
sql
postgresql
Valentin Kuzub
quelle
quelle
Antworten:
Verwenden Sie das Schlüsselwort EXISTS für die Rückgabe TRUE / FALSE:
quelle
select exists(select 1 from contact where id=12) AS "exists"
exists
oder wenn ichlimit 1
einen starken Leistungsabfall habe, weil Postgres Seq Scan anstelle von Index Scan verwendet. Undanalyze
hilft nicht.Wie wäre es einfach:
wo
123
ist die Benutzer-ID des Stapels, den Sie einfügen möchten?Die obige Abfrage gibt entweder einen leeren Satz oder eine einzelne Zeile zurück, je nachdem, ob Datensätze mit der angegebenen Benutzer-ID vorhanden sind.
Wenn sich herausstellt, dass dies zu langsam ist, können Sie einen Index für erstellen
tbl.userid
.Damit dies auch dann der Fall ist, wenn Ihr Programm während des Stapels unterbrochen wird, sollten Sie sicherstellen, dass Sie die Datenbanktransaktionen ordnungsgemäß verwalten (dh, dass der gesamte Stapel in eine einzelne Transaktion eingefügt wird).
quelle
COUNT
wirkt auf eine verschachtelteSELECT
, die höchstens 1 Zeile hat (weil sich dasLIMIT
in der Unterabfrage befindet).Übrigens: Wenn Sie möchten, dass der gesamte Stapel im Falle eines Duplikats fehlschlägt , dann (unter Berücksichtigung einer Primärschlüsseleinschränkung)
wird genau das tun, was Sie wollen: entweder ist es erfolgreich oder es schlägt fehl.
quelle
Ich glaube, dass dies die Abfrage ist, die postgres zum Überprüfen von Fremdschlüsseln verwendet.
In Ihrem Fall können Sie dies auch auf einmal tun:
quelle
wie @MikeM betonte.
Mit dem Index bei Kontakt können die Zeitkosten normalerweise auf 1 ms reduziert werden.
quelle
Wenn Ihre Ergebnismenge eine Zeile enthält, müssen Sie diese nicht einfügen. Andernfalls fügen Sie Ihre Unterlagen ein.
quelle
Wenn Sie über die Leistung nachdenken, können Sie möglicherweise "PERFORM" in einer Funktion wie dieser verwenden:
quelle
Ich möchte einen anderen Gedanken vorzuschlagen speziell Ihren Satz anzusprechen: „Also ich , wenn eine einzelne Zeile aus der Charge überprüfen möchten in der Tabelle existiert , weil dann ich weiß , sie alle wurden eingefügt .“
Sie machen die Dinge effizient, indem Sie sie in "Stapel" einfügen, aber dann die Existenzprüfungen jeweils für einen Datensatz durchführen? Dies scheint mir nicht intuitiv zu sein. Also , wenn Sie sagen , „ Einsätze werden immer in Chargen getan “ Ich nehme an , Sie meinen Sie mehrere Datensätze mit einem Insert - Anweisung einfügen . Sie müssen erkennen, dass Postgres ACID-konform ist. Wenn Sie mehrere Datensätze (einen Datenstapel) mit einer Einfügeanweisung einfügen , müssen Sie nicht überprüfen, ob einige eingefügt wurden oder nicht. Die Anweisung besteht entweder oder sie schlägt fehl. Alle Datensätze werden eingefügt oder keine.
Auf der anderen Seite, wenn Ihr C # -Code einfach separate Einfügeanweisungen "setzt", zum Beispiel in einer Schleife, und in Ihrem Kopf ist dies ein "Stapel". Dann sollten Sie ihn tatsächlich nicht als "beschreiben". Einsätze erfolgen immer chargenweise ". Die Tatsache, dass Sie erwarten, dass ein Teil dessen, was Sie als "Stapel" bezeichnen, möglicherweise nicht eingefügt wird und daher eine Überprüfung erforderlich ist, legt den Schluss nahe, dass dies der Fall ist. In diesem Fall haben Sie ein grundlegenderes Problem. Sie müssen Ihr Paradigma ändern, um tatsächlich mehrere Datensätze mit einer Einfügung einzufügen, und auf die Überprüfung verzichten, ob die einzelnen Datensätze es geschafft haben.
Betrachten Sie dieses Beispiel:
Dies ist in der Tat das Paradigma für jede ACID-kompatible Datenbank. Nicht nur für Postgresql. Mit anderen Worten, Sie sind besser dran, wenn Sie Ihr "Batch" -Konzept korrigieren und zunächst keine zeilenweisen Überprüfungen durchführen müssen.
quelle