production_plan問題は、テーブルが各行の注文IDとその他の詳細をキャプチャする実際の環境に起因します。各行は、製品の生産が開始されたときと生産後に更新され、イベントのUTC時刻をキャプチャします。
生産ラインでいくつかの温度を収集する別のテーブルがありますtemperatures-UTCで保存されたものに関係なく、定期的に。
目標は、各製品の生産のために測定された温度のシーケンスを抽出することです。(次に、温度を処理する必要があります。値のチャートが作成され、監査目的で製品アイテムのドキュメントに添付されます。)
marc_sコメントの後に更新されました。元の質問では、インデックスは考慮されていませんでした。更新されたテキストは、次のことを考慮しています。コメントに記載されている元の測定値。
テーブルとインデックスは次の方法で作成されました。
CREATE TABLE production_plan (
        order_id nvarchar(50) NOT NULL,
        production_line uniqueidentifier NULL,
        prod_start DATETIME NULL,
        prod_end DATETIME NULL
);
-- About 31 000 rows inserted, ordered by order_id.
...
-- Clusteded index on ind_order_id.
CREATE CLUSTERED INDEX ind_order_id
ON production_plan (order_id ASC);
-- Non-clustered indices on the other columns.
CREATE INDEX ind_times
ON production_plan (production_line ASC, prod_start ASC, prod_end ASC);
------------------------------------------------------
-- There is actually more temperatures for one time (i.e. more
-- sensors). The UTC is the real time of the row insertion, hence
-- the primary key.
CREATE TABLE temperatures (
        UTC datetime PRIMARY KEY NOT NULL,
        production_line uniqueidentifier NULL,
        temperature_1 float NULL  
);
-- About 91 000 rows inserted ordered by UTC.
...
-- Clusteded index on UTC is created automatically 
-- because of the PRIMARY KEY. Indices on temperature(s)
-- do not make sense.
-- Non-clustered index for production_line
CREATE INDEX ind_pl
ON temperatures (production_line ASC);
-- The tables were created, records inserted, and the indices
-- created for less than 1 second (for the sample on my computer).
アイデアは、最初にproduction_line識別時にテーブルを結合し、次に温度UTC時間がアイテムの生産の開始/終了のUTC時間の間に収まるようにすることです。
-- About 45 000 rows in about 24 seconds when no indices were used.
-- The same took less than one second with the indices (for my data
-- and my computer).
SELECT pp.order_id,      -- not related to the problem 
       pp.prod_start,    -- UTC of the start of production
       pp.prod_end,      -- UTC of the end of production
       t.UTC,            -- UTC of the temperature measurement
       t.temperature_1   -- the measured temperature
  INTO result_table02
  FROM production_plan AS pp
       JOIN temperatures AS t
         ON pp.production_line = t.production_line
            AND t.UTC BETWEEN pp.prod_start
                          AND pp.prod_end
  ORDER BY t.UTC;
約24秒の時間は受け入れられませんでした。インデックスが必要だったことは明らかです。同じ操作にかかる時間は1秒未満でした(Microsoft SQL Management Studioの結果タブの下にある黄色の線の時間)。
でも...
2番目の問題は残っています
温度測定はあまり頻繁ではなく、測定場所は生産開始から少しずれているため、時間補正を行う必要があります。つまり、時間範囲の境界に2つのオフセットを追加する必要があります。私はこのようなクエリで終了しました:
-- About 46 000 rows in about 9 minutes without indices.
-- It took about the same also with indices 
-- (8:50 instead of 9:00 or so).
DECLARE @offset_start INT;
SET @offset_start = -60  -- one minute = one sample before
DECLARE @offset_end INT;
SET @offset_end = +60    -- one minute = one sample after
SELECT pp.order_id,      -- not related to the problem 
       pp.prod_start,    -- UTC of the start of production
       pp.prod_end,      -- UTC of the end of production
       t.UTC,            -- UTC of the temperature measurement
       t.temperature_1   -- the measured temperature
  INTO result_table03
  FROM production_plan AS pp
       JOIN temperatures AS t
         ON pp.production_line = t.production_line
            AND t.UTC BETWEEN DATEADD(second, @offset_start, pp.prod_start)
                          AND DATEADD(second, @offset_end, pp.prod_end)
  ORDER BY t.UTC;
計算では、DATEADD()インデックスが作成されたかどうかにほぼ関係なく、約9分かかります。
問題を解決する方法についてもっと考えると、修正された時間境界(オフセットが追加されたUTC)には、効率的な処理のために独自のインデックスが必要であるように思われます。一時的なテーブルを作成することが頭に浮かびます。次に、修正された列のインデックスを作成できます。その後、もう1つJOINを使用すると役立つはずです。その後、テーブルを削除できます。
一時テーブルの基本的な考え方は正しいですか?それを行うための他のテクニックはありますか?
あなたの提案をありがとう。ご提案いただいたインデックスのご紹介後、タイムリザルトを更新させていただきます。改善が見込まれる理由を教えてください。私はSQLソリューションを作成する際の実践的な経験に関する初心者です。
