Sql 第二个线程/选项卡运行到idle事件中),或者他在这两者之间返回
特别是为了最大限度地提高性能,您应该修复数据,而不是发明一个变通查询。插入时这可能是3毫秒,但选择后可能值20秒强>Sql 第二个线程/选项卡运行到idle事件中),或者他在这两者之间返回,sql,sql-server,tsql,Sql,Sql Server,Tsql,特别是为了最大限度地提高性能,您应该修复数据,而不是发明一个变通查询。插入时这可能是3毫秒,但选择后可能值20秒 编辑:如果多线程/多会话是错误插入的原因,您还需要执行一项检查,如果最近的返回时间
编辑:如果多线程/多会话是错误插入的原因,您还需要执行一项检查,如果
最近的返回时间
-否则用户可能会在tab1上返回,并在几秒钟后在tab2上记录为空闲,则会导致tab2进入空闲超时,因为用户只刷新了tab1。我有一次遇到了“天”的“相同”问题(不包括我们和假期的额外问题)
“计数”这个词给了我以下的想法:
create table Seconds ( sec INT);
insert into Seconds values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9), ...
select count(distinct sec) from times t, seconds s
where s.sec between t.timefrom and t.timeto-1
and id=10;
您可以将起始值剪切为0(我将“10”放在括号中)
最后
select count(distinct sec) from times t, seconds s,
(select min(timefrom) m from times where id=10) as m
where s.sec between t.timefrom-m.m and t.timeto-m.m-1
and id=10;
另外,你可以“忽略”例如,10秒,通过分开你放松一些压力,但获得速度
select count(distinct sec)*d from times t, seconds s,
(select min(timefrom) m from times where id=10) as m,
(select 10 d) as d
where s.sec between (t.timefrom-m)/d and (t.timeto-m)/d-1
and id=10;
当然,这取决于你必须查看的范围,但是一天或两秒钟应该可以工作(尽管我没有测试它)
有趣的问题。我最初的反应是一种可怕的反应:一个光标可能是有序的。但是我希望我们能找到一个比这个更好的解决方案。所以如果你想要求和(30-10,70-50,150-60),我不明白“150-75”这个词?“大部分不重叠”是什么意思?为什么重叠?明白了!你需要一条时间线…我正要睡觉,但这会让我睡上几天minutes@JaazCole-是的,我也用这个解决方案解决了这个问题…我最终将它安排为一个夜间作业,将结果插入数据仓库的一个表中,然后我会参考数据仓库中的表。如果您正在寻找实时数据,可能不可行……但不幸的是,这是我能找到的唯一解决方案。霍普弗利,这里的一位古鲁有更好的东西。遗憾的是,你不在Oracle,我很好奇那里的第二个解决方案是否更好。如果预期的重叠度不大于1,这听起来可能有效。虽然我可以将此模型扩展到我目前在样本中看到的重叠量,我觉得在连接方面,这在处理能力方面可能有点沉重。@JaazCole:看看吧,它适用于任何程度的重叠。只有集合中的最后一条记录贡献了它的全部经过时间;其他每一条记录只会对经过的时间进行扩展。我过去经常使用这种技术。此外,如果在(ID、TimeFrom、其他字段)上有索引,则应该执行联接。再次编写查询并查看查询计划。@JaazCole:重要-只需要一个自连接。对于额外的重叠度,不需要额外的连接。通过数学更好地生活!这似乎很有效,但我觉得我可能需要更多的细节指导-我在仔细检查内部结果集(求和之前),发现了一些负面影响..这是正常的,还是应该粘贴我正在使用的示例SQL?谢谢你的帮助。别介意最后的请求,我最后的评论似乎是关于GIGO数据的。谢谢你的帮助!如果我能控制应用程序的设计,我们将进行一次完全不同的讨论。不过,我很感谢你的意见。
SELECT SUM(C.N)
FROM (
SELECT A.N, ROW_NUMBER()OVER(ORDER BY A.N) RowID
FROM
(SELECT TOP 60 1 N FROM master..spt_values) A
, (SELECT TOP 720 1 N FROM master..spt_values) B
) C
WHERE EXISTS (
SELECT 1
FROM Times SE
WHERE SE.ID = 10
AND SE.TimeFrom <= C.RowID
AND SE.TimeTo >= C.RowID
AND EXISTS (
SELECT 1
FROM Times2 D
WHERE ID = SE.ID
AND D.TimeFrom <= C.RowID
AND D.TimeTo >= C.RowID
)
GROUP BY SE.ID
)
WITH Overlaps
AS
(
SELECT t1.Id,
TimeFrom = MIN(t1.TimeFrom),
TimeTo = MAX(t2.TimeTo)
FROM dbo.Times t1
INNER JOIN dbo.Times t2 ON t2.Id = t1.Id
AND t2.TimeFrom > t1.TimeFrom
AND t2.TimeFrom < t1.TimeTo
GROUP BY t1.Id
)
SELECT o.Id,
o.TimeFrom,
o.TimeTo
FROM Overlaps o
UNION ALL
SELECT t.Id,
t.TimeFrom,
t.TimeTo
FROM dbo.Times t
INNER JOIN Overlaps o ON o.Id = t.Id
AND (o.TimeFrom > t.TimeFrom OR o.TimeTo < t.TimeTo);
DECLARE @tmp TABLE (ID INT, GroupId INT, TimeFrom INT, TimeTo INT)
INSERT INTO @tmp
SELECT ID, 0, TimeFrom, TimeTo
FROM Times
ORDER BY Id, TimeFrom
DECLARE @timeTo int, @id int, @groupId int
SET @groupId = 0
UPDATE @tmp
SET
@groupId = CASE WHEN id != @id THEN 0
WHEN TimeFrom > @timeTo THEN @groupId + 1
ELSE @groupId END,
GroupId = @groupId,
@timeTo = TimeTo,
@id = id
SELECT Id, MIN(TimeFrom), Max(TimeTo) FROM @tmp
GROUP BY ID, GroupId ORDER BY ID
+----+----------+--------+
| ID | TimeFrom | TimeTo |
+----+----------+--------+
| 10 | 50 | 70 |
| 10 | 60 | 150 |
ID TIMEFROM TIMETO
10 10 30
10 50 70
10 75 150
create table Seconds ( sec INT);
insert into Seconds values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9), ...
select count(distinct sec) from times t, seconds s
where s.sec between t.timefrom and t.timeto-1
and id=10;
select count(distinct sec) from times t, seconds s
where s.sec between t.timefrom- (10) and t.timeto- (10)-1
and id=10;
select count(distinct sec) from times t, seconds s,
(select min(timefrom) m from times where id=10) as m
where s.sec between t.timefrom-m.m and t.timeto-m.m-1
and id=10;
select count(distinct sec)*d from times t, seconds s,
(select min(timefrom) m from times where id=10) as m,
(select 10 d) as d
where s.sec between (t.timefrom-m)/d and (t.timeto-m)/d-1
and id=10;