首先,我会(用我糟糕的英语)尝试解释我所拥有的和我需要的东西
我已经获得了TimeLine的活动列表。
事件是一些离散信号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]的值。[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]
答案 0 :(得分: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中提取的名称与自己进行比较。因此,在我看来,提取部分是完全没必要的。
如果没有它,最终的查询结果非常简单(至少在外观上)。
答案 1 :(得分:1)
关系数据存储的最基本概念之一是
这应该是你做的第一件事,然后你可以进入下一级优化查询,连接,制作索引等。
答案 2 :(得分:0)
我认为最慢的部分来自EventView definiton:
SELECT ... ( 'Alarm' + CAST(ID as nvarchar(MAX)) ) AS Col, ...
加入这样的计算字段会导致令人讨厌的性能损失。
不能你: