我试图用一个非常大的表(>100m 记录)做一些与我自己类似的事情,并发现使用 Offset / Limit 会降低性能。前 10m 条记录的偏移量(限制为 1)大约需要 1.5 分钟才能检索,并且它呈指数增长。通过记录 50m,我每次选择最多 3 分钟 - 即使使用子查询。
我在这里看到了一篇文章,其中详细介绍了有用的替代方案。
我稍微修改了一下以适应我的需要,并提出了一种可以很快获得结果的方法。
CREATE TEMPORARY TABLE
just_index AS SELECT ROW_NUMBER()
OVER (ORDER BY [VALUE-You-need]), [VALUE-You-need]
FROM [your-table-name];
这是一次性的——大约花了 4 分钟,但我得到了我想要的所有值下一步是创建一个函数,该函数将在我需要的“偏移”处循环:
create or replace
function GetOffsets ()
returns void as $$
declare
-- For this part of the function I only wanted values after 90 million up to 120 million
counter bigint := 90000000;
maxRows bigInt := 120000000;
begin
drop table if exists OffsetValues;
create temp table OffsetValues
(
offset_myValue bigint
);
while counter <= maxRows loop
insert into OffsetValues(offset_myValue)
select [VALUE-You-need] from just_index where row_number > counter
limit 1;
-- here I'm looping every 500,000 records - this is my 'Offset'
counter := counter + 500000 ;
end loop ;
end ;$$ LANGUAGE plpgsql;
然后运行函数:
select GetOffsets();
再次,一次性的时间量(我从大约 3 分钟获得我的偏移值之一到 3 毫秒获得我的偏移值之一)。然后从临时表中选择:
select * from OffsetValues;
就性能而言,这对我来说非常有效 - 如果我能提供帮助,我认为我不会继续使用偏移量。
希望这可以提高任何较大表的性能。