如何优化一个SQL查询,该查询显示两个相邻的行,并带有闭合的时间戳值?
我需要为postgresql创建一个查询,显示在100毫秒内发出的请求。postgresql表请求具有请求id request\u id和timestampcreate\u戳记 下面的Mu查询工作起来很慢如何优化一个SQL查询,该查询显示两个相邻的行,并带有闭合的时间戳值?,sql,postgresql,Sql,Postgresql,我需要为postgresql创建一个查询,显示在100毫秒内发出的请求。postgresql表请求具有请求id request\u id和timestampcreate\u戳记 下面的Mu查询工作起来很慢 select b1.create_stamp as st1, b2.create_stamp as st2, b1.request_id as b1_id, b2.request_id as b2_id, Cast(date_part('millisec
select
b1.create_stamp as st1,
b2.create_stamp as st2,
b1.request_id as b1_id,
b2.request_id as b2_id,
Cast(date_part('milliseconds', b1.create_stamp) as Integer) as msi1,
Cast(date_part('milliseconds', b2.create_stamp) as Integer) as msi2,
(date_part('milliseconds', b1.create_stamp) - date_part('milliseconds', b2.create_stamp)) as diff
from
request b1, request b2
where
(b1.request_id - b2.request_id) = 1
and (date_part('milliseconds', b1.create_stamp) - date_part('milliseconds', b2.create_stamp)) < 100
and (date_part('milliseconds', b1.create_stamp) - date_part('milliseconds', b2.create_stamp)) > 0
order by b1.request_id;
可能您可以通过使用子查询来简化查询
select b1.create_stamp as st1, b2.create_stamp as st2, b1.request_id as b1_id,
b2.request_id as b2_id, msi1, msi2, (msi1 - msi2) as diff
from
(
select * , Cast(date_part('milliseconds', create_stamp) as Integer) as msi1
from request
) b1
,
(
select * , Cast(date_part('milliseconds', create_stamp) as Integer) as msi2
from request
) b2
where
(b1.request_id - b2.request_id) = 1 and
(msi1 - msi2) < 100 and (msi1 - msi2) > 0
order by b1.request_id;
您希望使用滞后/超前来检查上一个值和下一个值。这应该比自联接快得多:
select r.*
from (select r.*,
lag(create_stamp) over (order by request_id) as prevcs,
lead(create_stamp) over (order by request_id) as nextcs
from request r
) r
where (date_part('milliseconds', r.create_stamp) - date_part('milliseconds', prevcs)) < 100 and
date_part('milliseconds', r.create_stamp) - date_part('milliseconds', prevcs)) > 0
) or
(date_part('milliseconds', nextcs) - date_part('milliseconds', r.create_stamp)) < 100 and
date_part('milliseconds', nextcs) - date_part('milliseconds', r.create_stamp)) > 0
)
同时使用滞后和超前的原因是返回一对中的两行。如果第一行足够,那么您只需要一个函数和where子句的一半
我注意到您最初的查询查看相邻的请求ID。这是你真正想要的吗?还是要按create_stamp对行进行排序?如果是这样,请更改partition by函数中的order by参数。考虑以下查询:
SELECT Q.*
FROM (
SELECT *, lag (create_stamp, 1) OVER (ORDER BY request_id) prev
FROM request
) Q
WHERE
create_stamp - prev <= interval '00:00:00.1';
它将返回所有行,以便在100ms内有上一行
1根据请求的顺序确定的前一个\u id-如果不是您想要的,请适当更改order by子句。发布您的表定义?请求id上是否有索引?如果在时间窗口内有两个以上的相邻记录,该怎么办?该表相当复杂,但只有两列是重要的:请求id主键-自动索引和时间戳请求id对于此问题不重要,IMHO。只有一个代理。可能需要作为平局破坏者,但我怀疑数据中是否存在任何平局。如果它们存在,则应该需要其他有效负载属性disambiguate@BrankoDimitrijevic . . . 这实际上使用了OP声称有效的问题的原始逻辑。不过,你是对的,它在午夜不起作用。是的,最初的逻辑在午夜是有缺陷的,但是我们所有的活动都是在白天进行的,非常好,谢谢。以防万一间隔“00:00:00.01”给出的差值为10milliseconds@anarinsky啊,对不起。我错过了小数点。编辑。