質問

今週初めに、実行時に重複する値を連続して除外することについて質問しました。いくつかの良い答えがありましたが、調べていたデータの量が遅くなり、実行不可能でした。

現在、データベースではイベント値はフィルタリングされていません。データ値が重複します (タイムスタンプが異なります)。そのデータは実行時に処理する必要があり、データベース レベルでは時間がかかりすぎます (ストアド プロシージャで頻繁に使用されるため、コードにデータを取り込むことができません) 結果としてクエリ時間が長くなります。実行時に追加のフィルタリングが必要ないように、このデータ ストアがフィルタリングされてクエリが実行できるデータ構造が必要です。

現在DB内にあります

  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'1'、'2008-05-08 04:03:47.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'0'、'2008-05-08 10:02:08.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'0'、'2008-05-09 10:03:24.000' (これを削除する必要があります) **
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'1'、'2008-05-10 04:05:05.000'

私たちの必要なもの

  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'1'、'2008-05-08 04:03:47.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'0'、'2008-05-08 10:02:08.000'
  • 'F07331E4-26EC-41B6-BEC5-002AACA58337'、'1'、'2008-05-10 04:51:05.000'

これは些細なことのように思えますが、問題は、このデータを無線デバイスから取得するため、パケットの順序が狂い、ゲートウェイがマルチスレッドであるため、取得した値が正しいかどうかを保証できないことです。4 秒前に「1」、2 秒前に「0」のように何かが入ってくる可能性がありますが、「1」は最初に入ったものであるため、すでに処理されています。私たちはこれをどのように実装するかについて頭を悩ませています。最新の値が実際にはまだ入っていない可能性があるため、データをデータベース内の最新の値と比較することはできません。そのため、そのデータを破棄すると失敗し、シーケンスが完全に狂う可能性があります。したがって、現在は、入ってくるすべての値を保存し、データベースは時間に基づいて自動的にシャッフルします。ただし、イベントはまだアクティブであるため、ユニットは 1,1,1,0 を送信でき、それは有効ですが、オンとオフの状態のみを保存したいと考えています (オン状態の最初の発生は 1,0,1,0,1、 0)..トリガーについて考えましたが、新しい値が入るたびにデータをシャッフルする必要がありました。それは、それが最後のメッセージより早い可能性があり、シーケンス全体が変更される可能性があるためです(挿入が遅くなる可能性があります)。

何か案は?

さらに詳しい情報が必要かどうか尋ねてください。

[編集] PK が機能しません - 問題は、ユニットが実際に異なるタイムスタンプを送信することです。1,1,1 は同じなので、PK は機能しません。ただし、タイムスタンプが異なります。イベントは time1 で進行し、イベントは time2 でまだ進行中であるため、両方とも送り返されます。同じ値でも時間は異なります。

役に立ちましたか?

解決

アップデートの解決策は次のとおりです。パフォーマンスはインデックスによって異なります。

DECLARE @MyTable TABLE
(
  DeviceName varchar(100),
  EventTime DateTime,
  OnOff int,
  GoodForRead int
)

INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-08 04:03:47.000' 
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-08 10:02:08.000' 
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 0, '2008-05-09 10:03:24.000'
INSERT INTO @MyTable(DeviceName, OnOff, EventTime)
SELECT 'F07331E4-26EC-41B6-BEC5-002AACA58337', 1, '2008-05-10 04:05:05.000' 

UPDATE mt
SET GoodForRead = 
CASE
  (SELECT top 1 OnOff
   FROM @MyTable mt2
   WHERE mt2.DeviceName = mt.DeviceName
     and mt2.EventTime < mt.EventTime
   ORDER BY mt2.EventTime desc
  )
  WHEN null THEN 1
  WHEN mt.OnOff THEN 0
  ELSE 1
END
FROM @MyTable mt
    -- Limit the update to recent data
--WHERE EventTime >= DateAdd(dd, -1, GetDate())

SELECT *
FROM @MyTable

これに基づくフィルタリング ソリューションを想像するのは難しくありません。それは、各レコードの前のレコードをどのくらいの頻度で検索するか (クエリごとまたは時々) によって異なります。

他のヒント

私の理解が正しければ、あなたがやりたいことは、単に複製がデータベースに入るのを防ぐことです。その場合は、最初の 2 つの列に PK (または一意のインデックス) を定義して、面倒な作業をデータベースに実行させてみてはいかがでしょうか。定義した PK または AK に基づいて重複挿入は失敗します。コード (またはストアド プロシージャ) は、その例外を適切に処理するだけで済みます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top