2016-06-24 9 views
0

2億個のレコードにまたがるテーブルがあり、次のクエリを実行しようとしています。クエリは、前のレコードのタイムスタンプに基づいてテーブルを更新しようとします。このクエリをより速く実行させる方法はありますか?クロスレコードUPDATEクエリのチューニング

UPDATE [dbo].[Location Data] 
    SET [timestamp_prev] = 
    (
      SELECT [timestamp] FROM [dbo].[Location Data] newTable 
       WHERE [dbo].[Location Data].[RowNumber] = (newTable.[RowNumber] + 1) 
       AND [dbo].[Location Data].[mmsi] = newTable.[mmsi] 
    ); 
+0

クエリプランを確認します。実際に相関サブクエリを実行しているのですか、それとも自己結合に変換しましたか?もしそうでなければ、それを行うべきです。 – Blorgbeard

+0

あなたが使用している 'SQL Serverのどのバージョン ' –

答えて

2

このような単純なインデックスは良いスタートでなければなりません

UPDATE 
    t1 
SET 
    t1.[timestamp_prev] = t2.[timestamp] 
FROM 
    [dbo].[Location Data] t1 
INNER JOIN 
    [dbo].[Location Data] t2 
    ON t1.[RowNumber] = t2.[RowNumber] + 1 AND 
     t1.[mmsi] = t2.[mmsi] 

あなたが結合列にインデックスを持っている場合、このクエリは前に終了かもしれませんあなたは引退する。

0

インナーは以下のように参加し、むしろそれはあなたのネストされたクエリと同じように、テーブルの各行ごとのテーブルのすべての行を反復処理よりも役立つかもしれません。

UPDATE oldTable 
SET oldTable.[timestamp_prev] = newTable.[timestamp] 
FROM [dbo].[Location Data] oldTable 
INNER JOIN [dbo].[Location Data] newTable 
    ON oldTable.[RowNumber] = newTable.[RowNumber] + 1 
       AND oldTable.[mmsi] = newTable.[mmsi] 
0

私はこのような何かをしようとするだろう:

UPDATE T1 SET 
    [timestamp_prev] = T2.[timestamp] 
FROM [dbo].[Location Data] T1 
    INNER JOIN [dbo].[Location Data] T2 
     ON T1.RowNumber = T2.RowNumber + 1 
      AND T1.mmsi = T2.mmsi 
WHERE T1.[timestamp_prev] IS NULL; 

、より効率的である必要があり参加し、唯一の前のタイムスタンプを持っていないレコードを更新しよう。 RowNumber、MMSI、およびTimestamp_Prevのインデックスをテーブルに追加する別の手順を実行して、効率を最大限にするためのきれいなインデックスの検索を確実に行うことができます。あなたが自己結合を使用して試みることができる

CREATE NONCLUSTERED INDEX ix_Location_Data_MMSI_RowNumber_Timestamp_Prev 
    ON dbo.[Location Data] (mmsi, RowNumber, Timestamp_Prev) INCLUDE (Timestamp); 
2

まず、私はlag()を使用してこの操作を行います。

with toupdate as (
     select ld.*, 
      lag(timestamp) over (partition by mmsi order by RowNumber) as prev_timestamp 
     from dbo.[Location Data] ld 
    ) 
update toupdate 
    set timestamp_prev = prev_timetamp; 

その後、I 200万件のレコードを更新することは、長い、長い、長い時間がかかるために起こっていることに注意します。私はあなたが必要な列を持つ新しいテーブルを生成し、元のテーブルを切り捨て、それを再設定することをお勧めします。

+1

いいです**遅れ**。これが存在することさえ知りませんでした! – Sam

+1

@Sam [LAG](https://msdn.microsoft.com/en-IN/library/hh231256.aspx)が「SQL SERVER 2012」に導入されました –

+2

@Prdpサムが「遅れている」と思っていました:-) –