2016-05-20 3 views
0

私は次のストアドプロシージャを使用して、毎日サーバーにダウンロードされる数百種類のJSONファイルをループします。SQLサーバーのループのopenrowsetのパフォーマンス

問題は、実行するには15分かかりますが、JSONファイルを大量にするとすぐに同様のものを作成する必要があります。誰かが正しい方向に私を指揮することができますクエリの?

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 

答えて

0

ループ内のBULK INSERTがボトルネックと思われます。一般に、BULK INSERTはデータを取得する最も速い方法です。とにかく、ここではファイルの量があなたの問題だと思われます。

JSONファイルを並行して読みたい場合は、処理速度を上げるために、最初に、すべてのファイルに対して、または一部のファイルグループに対して、完全な動的SQLクエリを作成し、同時に読み込むことで、これを実行できます。

私はむしろ、並列データフロータスクのソースとしてスクリプトコンポーネントを使用してIntegration Servicesを使用することをお勧めします。最初に目的のフォルダからすべてのファイルを読み込み、たとえば4つのグループに分割します。グループごとに並列に実行されるループコンテナがあります。実行マシンに応じて、可能な限り多くの並列フローを使用できます。すべての2つのデータフローは、統合サービスのオーバーヘッドを補うものでなければなりません。

もう1つの方法は、CLR (common language runtime) stored procedureを書き、JSONをC#を使用して並列に逆シリアル化することです。

また、ジョブを実行しているマシンによって異なります。十分なランダムアクセスメモリとCPUの消費電力が必要なので、マシンがビジーでない間にインポートを実行する必要があります。

0

多くの個々のXMLファイルのテーブルにデータをロードするときに成功した方法の1つは、SQL ServerのFileTable機能を使用することです。

データベースにファイルテーブルを設定し、XMLファイルをアップロードしていたプロセスのサーバーで作成されたFileStream共有にアクセスできるようにしました。 XMLファイルは共有にドロップされ、xPathを使用してクエリを実行するためにデータベースですぐに使用できました。

プロセスが実行されると、xPathクエリはXMLから必要なデータを必要なテーブルにロードし、ロードされたファイルを追跡し、次のスケジュールが来たら最新のファイルからのみデータをロードします。

マシン上のスケジュールされたタスクは、不要になったファイルを削除します。

はここFileTable内にまで読みました:

FileTables (SQL Server)

これは、すべてのSQL Serverのエディションで利用可能です。

関連する問題