1

我需要为 postgresql 创建一个查询,显示在 100 毫秒内发出的请求。postgresql 表请求具有请求 id (request_id) 和时间戳 (create_stamp)。

下面的 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('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;
4

3 回答 3

2

您想使用lag()/lead()检查上一个和下一个值。这应该比自加入快得多:

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
      )

lag()使用两者的原因lead()是返回一对的两行。如果第一个这样的行就足够了,那么您只需要一个函数(和一半的where子句)。

我注意到您的原始查询会查看相邻的请求 ID。这是你真正想要的吗?或者你想按顺序排列行create_stamp吗?如果是这样,order by请按函数更改分区中的参数。

于 2013-06-30T17:40:51.893 回答
1

考虑以下查询:

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';

[SQL 小提琴]

它将返回所有行,以便在 100 毫秒内有前1行。


1 “上一个”由request_id- 如果不是您想要的,请适当更改 ORDER BY 子句的顺序。

于 2013-06-30T18:06:00.597 回答
0

可能您可以使用子查询来简单地查询

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;
于 2013-06-30T17:38:30.193 回答