我正在运行一项查询,其中我查找一条记录,并在一定时间后查找另一条记录。
表定义:
(
id integer primary key,
gpsstatus character(2),
datetime timestamp without time zone,
lat numeric(9,6),
lon numeric(9,6),
alt numeric(9,4),
time integer,
datafileid integer,
shape geometry,
speed double precision,
dist double precision,
shape_utm geometry,
lokalitet character(128),
cowid integer
)
datetime、lokalitet、cowid 和 gpsstatus 都有索引,shape 和 shape_utm 上有 gist 索引。
应该每5秒钟采样一次点,所以我尝试执行:
select <something more>,p1.timestamp
from table p1, table p2
where p1.timestamp + interval '5 secound' = p2.timestamp
这段代码运行速度相当快,但后来我发现由于采样时抖动,导致失去了许多点,因此这些点之间可能相隔4到6秒。
接着尝试了以下方法:
where (p2.timestamp, interval'0 second')
overlaps (p1.timestamp + interval '4 second', interval '2 second')
这花了我很长时间。我也尝试了更简单的解决方案:
WHERE p1.timestamp + interval '4 second' <= p2.timestamp
AND p1.timestamp + interval '6 second' >= p2.timestamp
该查询最终变得无法使用。
时间戳字段具有普通索引。是否有特殊类型的索引或其他内容,可以使此查询可用?
目前的查询:
SELECT
p1.cowid,
p1.datetime,
st_distance(p1.shape_utm, lead(p1.shape_utm)
OVER (ORDER BY p1.datetime)) AS meters_obs,
st_distance(p1.shape_utm, lead(p1.shape_utm, 720)
OVER (ORDER BY p1.datetime)) AS meters_hour,
observation.observation
FROM (gpspoint p1 LEFT JOIN observation
ON (observation.gpspointid = p1.id)),
status
WHERE p1.gpsstatus = status.id
AND status.use = true;
通过请求一些特定的时间间隔,我也可以获得可接受的查询时间。
TIMESTAMP WITHOUT TIME ZONE
和CHAR(n)
类型。这两种类型仅用于符合标准,且都具有非常令人惊讶的语义,往往会咬到使用它们的人。如果要记录时间点,请考虑使用TIMESTAMP WITH TIME ZONE
(也称为timestamptz
)。在PostgreSQL中,VARCHAR(n)
几乎普遍更安全和更快,没有关于尾随空格的令人惊讶的语义;许多人只使用text
,在PostgreSQL中,这与没有长度约束的VARCHAR(n)
相同。 - kgrittn