2012-06-19 10 views
15

Meine Firma ist verflucht von einer symbiotischen Partnerschaft parasitär geworden. Um unsere Daten vom Parasiten zu erhalten, müssen wir eine schmerzhaft langsame ODBC-Verbindung verwenden. In letzter Zeit ist mir jedoch aufgefallen, dass ich durch paralleles Ausführen von Abfragen (sogar in der gleichen Tabelle) mehr Durchsatz erzielen kann.Schnellste Art und Weise parallel zu einer einzigen Tabelle einfügen

Es gibt eine besonders große Tabelle, aus der ich Daten extrahieren und in unsere lokale Tabelle verschieben möchte. Abfragen parallel ausführen Ich kann Daten schneller abrufen, aber ich stelle mir auch vor, dass dies Probleme beim Versuch, Daten aus mehreren Abfragen gleichzeitig in dieselbe Tabelle zu schreiben, verursachen könnte.

Welchen Rat können Sie mir geben, wie ich diese Situation am besten behandeln kann, damit ich die erhöhte Geschwindigkeit der parallelen Verwendung von Abfragen nutzen kann?

EDIT: Ich habe hier ein tolles Feedback erhalten, aber ich glaube nicht, dass ich die Daten über einen Verbindungsserver (der die odbc-Treiber verwendet) übermittele. Mit anderen Worten, das bedeutet, dass ich normale INSERT-Anweisungen ausführen kann und ich glaube, das würde eine bessere Leistung als SqlBulkCopy oder BULK INSERT bieten (eigentlich glaube ich nicht, dass BULK INSERT sogar eine Option wäre).

+0

Wie Sie vorgeschlagen haben, werden parallele Schreiboperationen wahrscheinlich nicht zur Leistung beitragen. Vielleicht finden Sie hier einige Antworten http://stackoverflow.com/questions/2861944/how-do-i-do-very-fast-inserts-to-sql-server-2008 –

+0

Migrieren Sie die Daten? Ich frage, weil Sie Ihre Bewegungsdaten an lokale Tabellen gesendet haben. Auch wie geht das in Code zB C# oder als Teil eines SQL-Jobs? –

+0

@mouters Ja, aber neue Daten kommen nicht in unsere Datenbank, daher muss ich jeden Tag etwas Neues kopieren. Bisher habe ich es in SSM mit der Hand gemacht, aber die parallele Idee wird in C# gemacht, wenn ich das tue. Wahrscheinlich werde ich das nicht parallel machen b/c Ich habe jetzt alle historischen Daten und muss nur einen SQL-Job einrichten, um jeden Abend neue Daten zu bekommen. Aber ich wollte nur ein paar Infos über die Idee b/c bekommen, die ich in naher Zukunft für andere Sachen dafür verwenden könnte. –

Antwort

12

Haben Sie Load 1TB in less than 1 hour gelesen?

  1. laufen so viele Ladeprozesse, wie Sie verfügbaren CPUs haben. Wenn Sie 32 CPUs mit haben, führen Sie 32 parallele Lasten aus. Wenn Sie über 8 CPUs verfügen, führen Sie 8 parallele Lasten aus.
  2. Wenn Sie Kontrolle über die Erstellung Ihrer Eingabedateien haben, machen Sie sie einer Größe, die durch die Anzahl der Lade-Threads gleichmäßig teilbar ist, die Sie parallel ausführen möchten. Stellen Sie außerdem sicher, dass alle Datensätze zu einer Partition gehören, wenn Sie die Switch-Partitionsstrategie verwenden möchten.
  3. Verwenden Sie BULK-Einfügung anstelle von BCP, wenn Sie den Prozess auf dem SQL Server-Computer ausführen.
  4. Verwenden Sie Tabellenpartitionierung, um weitere 8-10% zu erhalten, aber nur, wenn Ihre Eingaben GARANTIERT sind, um Ihrer Partitionierungsfunktion zu entsprechen, dh , dass alle Datensätze in einer Datei in derselben Partition sein müssen.
  5. Verwenden Sie TABLOCK, um eine gleichzeitige Zeilensperrung zu vermeiden.
  6. Verwenden Sie ROWS PRO BATCH = 2500, oder etwas in der Nähe, wenn Sie mehrere Streams in eine Tabelle importieren.

Für SQL Server 2008 gibt es bestimmte Situationen, in denen Sie minimal logging for a standard INSERT SELECT nutzen können:

SQL Server 2008 verbessert die Methoden, die es mit minimalen Protokollierung verarbeiten kann. Es unterstützt minimal protokollierte reguläre INSERT SELECT Anweisungen. Durch Aktivieren des Ablaufverfolgungsflags 610 kann SQL Server 2008 außerdem die minimale Protokollierung gegen eine nichtleere B-Struktur für neue Schlüsselbereiche unterstützen, die Zuordnungen neuer Seiten verursachen.

+0

Danke, das ist gut, aber wirklich nicht anwendbar (außer # 1) auf meine Situation, weil ich nicht Daten von einer Datei laden, sondern von einem verbundenen Server über odbc Treiber ... so mache ich regelmäßig Set-basierte Insert-Anweisungen sowieso. Also frage ich mich, wie ich das Gleiche tun würde, wenn ich ROWS PER BATCH auf eine normale Insert-Anweisung setze, oder wenn ich das kann? –

+0

Verwenden Sie SQL Server 2008 oder höher? Die minimale Protokollierung von Standard-INSERT SELECT-Anweisungen wird unter bestimmten Umständen unterstützt. – 8kb

3

Wenn Ihr auf der Suche diese C# im Code also zu tun besteht die Möglichkeit, SqlBulkCopy zu verwenden (im System.Data.SqlClient-Namespace) und wie dieser Artikel schlägt vor, die Möglichkeit, das parallel zu tun.

http://www.adathedev.co.uk/2011/01/sqlbulkcopy-to-sql-server-in-parallel.html

+0

Das einzige Ding, das schlecht ist, etwas Masse zu tun ist, dass Sie Indizes später neu erstellen müssen, da es sie auf der Einfügung ignoriert. – SQLMason

+0

Nun, ich habe gerade darüber nachgedacht, mit C# die Parallelisierung zu verwalten. Ich glaube nicht, dass die Verwendung von SqlBulkCopy schneller ist als die Verwendung von SqlCommand.ExecuteNonQuery(), um die gleiche Set-basierte Insert-Anweisung zu erstellen, die ich direkt von SSMS ausführen würde, oder? Ich denke, eine Sache, die Leute beantworten, vergisst, dass dies nicht aus einer flachen Datei kommt ... Ich habe Zugang zu regulären Insert-Anweisungen direkt auf den Quelldaten. –

+0

Ich nehme an, wenn Sie das sagen "die gleiche Set-basierte Insert-Anweisung" Sie meinen, Sie sind in der Lage, eine Cross-Datenbank Join zu tun? Versuchen Sie auch, in die Quelle einzufügen, oder meinen Sie nur, dass Sie Lese-/Schreibzugriff auf die Quelldatenbank haben (aber im Grunde genommen irrelevant für das, was Sie hier versuchen)? –

Verwandte Themen