我具有下表:行與最接近的列值
CREATE TABLE items (
id serial
timestamp bigint
CONSTRAINT id_pkey PRIMARY KEY (id),
);
此表是在僅追加-方式使用,所以timestamp
值與id
增加。我需要找到誰的timestamp
是最接近特定$value
行。
查詢1:這需要兩個全表掃描。
SELECT id FROM
(
(
SELECT id, timestamp
FROM records
WHERE timestamp < $value
ORDER BY timestamp DESC
LIMIT 1
)
UNION ALL
(
SELECT id, timestamp
FROM items
WHERE timestamp >= $value
ORDER BY timestamp ASC
LIMIT 1
)
) AS tmp
ORDER BY abs($value - timestamp)
LIMIT 1
查詢2:這一個看起來像它應該更快,但由於某種原因它不是
SELECT id
FROM items
WHERE scan.gpstimestamp >= $value
ORDER BY id ASC
LIMIT 1
問題3:我與需要全表掃描一個自定義聚合試驗,但不需要對任何東西進行排序或加載任何索引。
create function closest_id_sfunc(
agg_state bigint[2],
id bigint,
timestamp bigint,
target_timestamp bigint
)
returns bigint[2]
immutable
language plpgsql
as $$
declare
difference bigint;
begin
difference := abs(timestamp - target_timestamp);
if agg_state is null or difference < agg_state[0] then
agg_state[0] = difference;
agg_state[1] = id;
end if;
return agg_state;
end;
$$;
create function closest_id_finalfunc(agg_state bigint[2])
returns bigint
immutable
strict
language plpgsql
as $$
begin
return agg_state[1];
end;
$$;
create aggregate closest_id (bigint, bigint, bigint)
(
stype = bigint[2],
sfunc = closest_id_sfunc,
finalfunc = closest_id_finalfunc
);
SELECT closest_id(id, timestamp, $value) as id FROM items
爲什麼查詢2比查詢1慢?
是用戶指定的時間戳還是數據庫指定它?換句話說,我們可以在id之前和之後獲取行,而不是使用時間戳字段來使用這些行嗎?另外,在時間戳字段上創建索引是一個選項嗎? – user1327961
緩慢是由於全表掃描,因爲正在對未編制索引的字段進行比較。 – user1327961
時間戳是用戶指定的,並且我不能在其上放置索引(不要問:S ...) –