1

まず、私は(私の悪い英語で)私が持っているものと私が持っている必要があるものを説明しようとします

タイムラインごとのイベントのリストを取得しました。

イベントは、ある時間に発生し、ある期間を得た離散信号1/0です。

私のイベントリストは次のようになっています

Rectime - start event time
Col - event name
ChangedDate - end event time
InitalValue - event message
Value - event state 1/0

そして、これらのイベントは、 A1イベントが1である場合、A2が0であるか、A5が1である場合に、いくつかの複雑なイベントを呼び出すことができます。

私の複雑なイベント(インシデント)の構造は次のとおりです。

[ID] - just ID
[Name] - just Name 
[SQL] - here is list of event names with logics alike ***(A1 AND NOT A2) OR A5***
[Message] - event message

考えられる変更を見逃す必要はないので、何らかのイベントが発生したときに変更される可能性のある複雑なイベントを探していますが、変更された複雑なイベントがあるかどうかを知るには、この複雑なイベントに依存する他のイベントについて知る必要があります。次のステップはすべての依存イベントとその状態を1/0で取得します。これが私の試みです:

With DependencedIncidents AS -- Get all dependenced Incidents from this Event
(
    SELECT INC.[RecTime],INC.[SQL] AS [str] FROM
    (
        SELECT A.[RecTime] As [RecTime],X.[SQL] As [SQL] FROM [EventView] AS A 
        CROSS JOIN [Incident] AS X
            WHERE
                patindex('%' + A.[Col] + '%', X.[SQL]) > 0
    ) AS INC
)
, DependencedEvents AS -- Split SQL string to get dependeced Events for each dependeced Incident
(
    select distinct word AS [Event] , [RecTime]
    from
    (
        select v.number, t.[RecTime] As [RecTime],
            substring(t.str+')',
                      v.number+1,
                      patindex('%[() ]%',
                               substring(t.str+')',
                                         v.number+1,
                                         1000))-1) word
        from DependencedIncidents AS t
        inner join master..spt_values v on v.type='P'
          and v.number < len(t.str)
          and (v.number=0 or substring(t.str,v.number,1) like '[() ]')
    ) x
    where word not in ('','OR','AND')
)
, EventStates AS -- Dependeced events with their states 1/0
(
    Select D.[RecTime], D.[Event], X.[Value]
    From [DependencedEvents] AS D
    LEFT JOIN [EventView] AS X 
        ON X.Col = D.[Event]
        AND D.[Rectime] >= X.[Rectime]
        AND D.[Rectime] <= X.[ChangedDate]
)

select * from EventStates
order by [RecTime]

そしてそれは非常に遅く動作します、それが可能であれば私は真剣な最適化が必要です。

最も遅い(時間の95%)部分は

LEFT JOIN [EventView] AS X 
    ON X.Col = D.[Event]
    AND D.[Rectime] BETWEEN X.[Rectime] AND  X.[ChangedDate]

多分私はここで何か間違ったことをしている...

今回はEventViewからD.[Event]の値を確認したいだけです。D。[Rectime]..。

コメントリクエストによって追加されたeventview:

ALTER VIEW [dbo].[EventView] AS
            (SELECT RecTime, ChangedDate, ( 'Alarm' + CAST(ID as nvarchar(MAX)) ) AS Col, InitialValue, Value FROM [dbo].[Changes]
                WHERE InitialValue <> '')
            UNION ALL
            SELECT RecTime, ChangedDate, Col, InitialValue, Value FROM [dbo].[XDeltaIntervals]
            UNION ALL
            SELECT RecTime, ChangedDate, Col, InitialValue, Value FROM [dbo].[ActvXDeltaIntervals]
4

3 に答える 3

2

私はこれがほぼ同じであるべきだと思います:

SELECT
  ev.Rectime,
  ev.Event,
  ev2.Value
FROM EventView AS ev
  INNER JOIN Incident i
    ON PATINDEX('%' + ev.Col + '%', i.SQL) > 0
  LEFT JOIN EventView ev2
    ON ev.Col = ev2.Col AND ev.Rectime BETWEEN ev2.Rectime AND ev2.ChangedDate

重要なのは、イベント名を使用して複雑なイベントを見つけ、見つかった複雑なイベントからそれらの名前を抽出し、最後に最後のCTEで抽出された名前を使用してそれらと比較することです。ですから、抽出部分は全く不要に思えました。

そして、それがなければ、結果のクエリは非常に単純であることがわかりました(少なくとも外観上)。

于 2011-03-21T14:50:37.127 に答える
1

リレーショナルデータストレージの最も基本的な概念の1つは、

  • 正規化された方法でデータを保存し、
  • リレーショナルデータベースを使用してデータを保存しますが、データの解析/処理などは行わないでください。これを行うには、アプリケーション層を使用します。

それを最初に行う必要があります。その後、クエリの最適化、結合、インデックスの作成などの次のレベルに進むことができます。

于 2011-03-21T11:13:34.063 に答える
0

最も遅い部分は、EventViewの定義に由来すると思います。

SELECT ... ( 'Alarm' + CAST(ID as nvarchar(MAX)) ) AS Col, ...

このような計算フィールドと結合すると、パフォーマンスが低下します。

できません:

  • (Col =)Alarm+IDをChangesテーブルに直接記録するか
  • トリガーまたはトリガーによってAlarm+IDを更新します
  • インデックス付きビューを使用してAlarm+IDを計算するまたは
  • アラーム+IDまたは少なくともを保存するために一時テーブルを使用する
  • nvarchar(MAX)ではなく、nvarchar(10)のようなものを使用します(これによりクエリプランが変更された場合)

于 2011-03-23T08:21:55.437 に答える