Sql 第二个线程/选项卡运行到idle事件中),或者他在这两者之间返回

Sql 第二个线程/选项卡运行到idle事件中),或者他在这两者之间返回,sql,sql-server,tsql,Sql,Sql Server,Tsql,特别是为了最大限度地提高性能,您应该修复数据,而不是发明一个变通查询。插入时这可能是3毫秒,但选择后可能值20秒 编辑:如果多线程/多会话是错误插入的原因,您还需要执行一项检查,如果最近的返回时间

特别是为了最大限度地提高性能,您应该修复数据,而不是发明一个变通查询。插入时这可能是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;