2009-07-29 11 views
6

Ich möchte n Datensätze in eine einzige Tabelle einfügen. Es kann viele gleichzeitige Benutzer geben und sie können Daten aus dieser Tabelle einfügen/aktualisieren/auswählen. Gibt es eine bessere Art und Weise ist in einer solchen Tabelle sagen 1000 Datensätze einzufügen:SQL-Abfrage Leistung einfügen

  1. einer einzigen SQL-Abfrage an eine Datenbank mit mehreren Einsätzen senden. Dies spart Server für Datenbankaufrufe, aber (ich bin mir nicht sicher) sperrt die Tabelle, bis die Einfügung abgeschlossen ist und alle anderen Abfragen an diese Tabelle warten.
  2. Teilen Sie 1000 Datensätze in einigen Chunks und senden Sie sie in mehreren SQL-Abfragen. Auf diese Weise können die anderen Abfragen in der Tabelle ausgeführt werden, es wird jedoch Zeit für Server-zu-Datenbank-Aufrufe benötigt.

Ist das etwas hängt, oder gibt es eine einzige Art und Weise, die immer die optimale ist? Kommt es darauf an, ob Transaktionen verwendet werden oder nicht, während Daten eingefügt werden? Gibt es andere bessere Möglichkeiten, einen solchen Einsatz durchzuführen?

Die Datenbank Ich benutze MS SQL, aber es ist interessant, wie es in anderer DB wie Oracle arbeitet.

Antwort

6

Das hängt völlig ab, was RDBMS Sie verwenden.

In Oracle, schreibt nie Block liest, das ist, warum Sie Ihre Daten sicher auf einmal setzen. Beachten Sie jedoch, dass dies die Leistung beeinträchtigt, da die gleichzeitigen Abfragen die Daten aus dem Tabellenbereich UNDO abrufen müssen, der zusätzliche Lesevorgänge erfordert.

In SQL Server schreibt Blockierungen auf betroffene Zeilen/Seiten/Tabellen (abhängig von Lock-Eskalationsproblemen), es sei denn, Sie setzen TRANSACTION ISOLATION LEVEL auf SNAPSHOT.

In allen Transaktions Motoren, die gleichzeitige Schreiben und Lesen zu ermöglichen, muss der Motor irgendwo sowohl alte als auch neue Daten speichern, für die es zur gleichen Zeit zur Verfügung stehen.

In Oracle werden alte Daten in den UNDO Tablespace kopiert.

In SQL Server, wird es in tempdb kopiert (nur bei SNAPSHOT Isolation aktiviert ist, sonst ist es nur gesperrt).

Dies erfordert immer einige Ressourcen (Arbeitsspeicher oder Festplatte), und Sie können diese Ressourcen ausgehen, wenn Ihre Abfrage UPDATE viele Zeilen betrifft.

1

Stellen eine Trennung (concurrency) Stufe, die während einer Transaktion liest der alten Daten können - z.B. SQL Server 2005+ hat READ SNAPSHOT.

2

gebloggt ich diesen a while ago - Ich denke, die Post einige Ihrer Fragen beantwortet. CKs Ratschlag ist vernünftig (und Quassno hat auch ein paar gute Punkte in Bezug auf Oracle), wenn Sie befürchten, dass die Leser die Autoren blockieren.

+0

interessante Blogpost +1. Es macht mein Interesse daran, dass die _reason_ Transaktionen in Ihrem Test schneller erscheinen. Ich vermute, das liegt daran, dass viele der notwendigen Schlösser bereits durch vorherige Pässe belegt wurden. Die eine entscheidende Sache, die Ihr Beitrag jedoch nicht anspricht, ist das Verhalten unter Last. Ihre Tests scheinen isoliert zu sein. In einem Live-System vermute ich, dass die Ergebnisse ziemlich schnell invertieren würden. – EBarr

2

Die allgemeine Regel ist, dass Sie die Datenbank herausfinden sollten, wie die Arbeit ausgeführt wird. Das funktioniert besser, je mehr Sie es in einer Anweisung sagen, d. H. Sie sollten die 1000 Datensätze auf einmal einfügen. Dies funktioniert am besten für meisten Datenbankservern und die meisten Server blockieren keine Lesevorgänge für Schreibvorgänge.

Es gibt Ausnahmen: Wenn die Einfügung langsam ist, weil der Server langsam oder die Tabelle groß oder kompliziert ist kann besser sein, die Abfrage in Gruppen von kleinen Einsätzen zu teilen.

Ein dazwischen Verfahren wäre für mehrere Einsatzbefehle zu senden, sagen wir 10 oder 100 Zeilen mit Festschreibungen dazwischen in einem großen Skript an den Server.

Hinzugefügt: Die meisten Datenbankserver blockieren das Lesen nicht wie in Oracle, IBM DB/2 und MySQl mit InnoDB -Tabellen. SQL Server hingegen kann Tabellen auch für Lesevorgänge sperren und gehört nicht dazu.

+1

Ich denke, dass Sie finden, dass die meisten DBs Probleme haben, wo Leser Schriftsteller blockieren (Oracle nicht). – RichardOD

+0

Microsoft ADO.NET-Kernreferenz empfiehlt die Verwendung von Stapelgrößen zwischen 100 und 1000. – RichardOD

+0

@RichardOD: Können Sie bitte einen Link zu dieser Empfehlung veröffentlichen? – Kamarey