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]

也许我在这里做错了什么......

我只想在这次 D.[Retime] 中从 EventView 中检查 D.[Event] 的值...

评论请求添加的事件视图:

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

关系数据存储的最基本概念之一是

  • 以标准化方式存储数据,并
  • 使用关系数据库来存储数据,但不要解析/处理它等。使用应用程序层来做到这一点。

这应该是你做的第一件事,然后你可能会进入下一个优化查询、连接、制作索引等的级别。

于 2011-03-21T11:13:34.063 回答
0

我认为最慢的部分来自 EventView 定义:

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

加入这样的计算字段会导致严重的性能损失。

你不能:

  • 将 (Col=)Alarm+ID 直接记录到 Changes 表或
  • 通过触发器更新警报+ID 或
  • 使用索引视图计算警报+ID 或
  • 使用临时表存储警报+ID 或至少
  • 不使用 nvarchar(MAX),而是使用 nvarchar(10) 之类的东西(如果这改变了查询计划)

?

于 2011-03-23T08:21:55.437 回答