2016-05-20 37 views
0

Ich habe die folgende gespeicherte Prozedur, um Hunderte von verschiedenen JSON-Dateien durchlaufen, die auf den Server jeden Tag heruntergeladen werden.SQL Server Schleife openrowset Leistung

Das Problem ist, dass die Abfrage dauert gut 15 Minuten zu laufen, muss ich etwas Ähnliches für eine größere Anzahl von JSON-Dateien bald erstellen, ist jemand in der Lage, mich in die richtige Richtung in Bezug auf die Leistung zu erhöhen der Abfrage?

DECLARE @json VARCHAR(MAX) = '' 
DECLARE @Int INT = 1 
DECLARE @Union INT = 0 
DECLARE @sql NVARCHAR(max) 
DECLARE @PageNo INT = 300 

WHILE (@Int < @PageNo) 
BEGIN 
    SET @sql = (
    'SELECT 
     @cnt = value 
    FROM 
     OPENROWSET (BULK ''C:\JSON\tickets' + CONVERT(varchar(10), @Int) + '.json'', SINGLE_CLOB) as j 
     CROSS APPLY OPENJSON(BulkColumn) 
    WHERE 
     [key] = ''tickets'' 
    ') 
EXECUTE sp_executesql @sql, N'@cnt nvarchar(max) OUTPUT', @[email protected] OUTPUT 

IF NOT EXISTS (SELECT * FROM OPENJSON(@json) WITH ([id] int) j JOIN tickets t on t.id = j.id) 
BEGIN 
    INSERT INTO 
     tickets (id, Field1) 
    SELECT 
     * 
    FROM OPENJSON(@json) 
     WITH ([id] int, Field1 int) 
END 

END 

Antwort

0

Es scheint, dass Ihr BULK INSERT in der Schleife der Flaschenhals ist. Im Allgemeinen ist ein BULK INSERT der schnellste Weg, um Daten zu erhalten. Wie auch immer, hier scheint die Menge an Dateien dein Problem zu sein.

Um die Dinge schneller zu machen, möchten Sie die JSON-Dateien parallel lesen. Sie können dies tun, indem Sie zuerst die vollständige dynamische SQL-Abfrage für alle Dateien oder vielleicht für einige Dateigruppen erstellen und gleichzeitig lesen.

Ich würde eher empfehlen, Integration Services mit einer Skriptkomponente als Quelle in parallelen Datenflussaufgaben zu verwenden. Lies zuerst alle Dateien aus deinem Zielordner, teile sie zum Beispiel in 4 Gruppen, für jede Gruppe hast du einen Loop-Container, der parallel läuft. Abhängig von Ihrem ausführenden Rechner können Sie so viele parallele Flüsse wie möglich verwenden. Bereits zwei Datenflüsse sollten den Overhead der Integrationsdienste ausgleichen.

Eine andere Option wäre ein CLR (common language runtime) stored procedure schreiben und JSON mit C# parallel deserialisieren.

Es hängt auch von der Maschine ab, die die Arbeit erledigt. Sie möchten genügend Arbeitsspeicher und freie CPU-Leistung haben, so sollte es in Betracht gezogen werden, den Import durchzuführen, während der Computer nicht beschäftigt ist.

0

Eine Methode, mit der ich erfolgreich Daten in Tabellen aus vielen einzelnen XML-Dateien geladen habe, die Sie möglicherweise auf dieses Problem anwenden können, ist die Verwendung der FileTable-Funktion des SQL-Servers.

Die Vorgehensweise bestand darin, eine Dateitabelle in der Datenbank einzurichten und dann den Zugriff auf die FileStream-Freigabe zuzulassen, die auf dem Server für den Prozess erstellt wurde, der die XML-Dateien hochgeladen hat. XML-Dateien wurden dann in die Freigabe eingefügt und waren sofort in der Datenbank für Abfragen mit xPath verfügbar.

Ein Prozess würde dann ausgeführt werden xPath-Abfragen würden die erforderlichen Daten aus dem XML in die erforderlichen Tabellen laden und verfolgen, welche Dateien geladen wurden. Wenn dann der nächste Zeitplan kam, laden Sie nur Daten aus den neuesten Dateien.

Eine geplante Aufgabe auf der Maschine würde dann Dateien entfernen, wenn sie nicht mehr benötigt wurden.

Haben auf Filetable hier ein nachlesen:

FileTables (SQL Server)

Es in allen SQL Server-Editionen verfügbar ist.