有序 postgresql 数组中大于 x 的最小值的位置(优化)
Posted
技术标签:
【中文标题】有序 postgresql 数组中大于 x 的最小值的位置(优化)【英文标题】:Position of the lowest value greater than x in ordered postgresql array (optimization) 【发布时间】:2021-06-08 22:54:53 【问题描述】:看postgres函数array_position(anyarray, anyelement [, int])
我的问题类似,但我正在寻找大于元素的数组中第一个值的位置。我在小数组上运行它,但非常大的表。
这行得通:
CREATE OR REPLACE FUNCTION arr_pos_min(anyarray,real)
RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'select array_position($1,(SELECT min(i) FROM unnest($1) i where i>$2))';
array_position 利用了我的数组是有序的这一事实,但第二部分没有。而且我觉得第二部分可能只是返回位置而无需重新查询。
我的数组只有 100 个元素长,但我必须运行数百万次,因此需要寻找性能提升。
建议表示赞赏。
【问题讨论】:
好吧,min()
并不真正关心订单。无论如何它都会查看所有值并返回最小值
不相关,但是:SQL函数可以使用参数名,不需要使用过时的$1和$1引用参数位置
【参考方案1】:
这似乎有点快
CREATE OR REPLACE FUNCTION arr_pos_min(p_input anyarray, p_to_check real)
RETURNS int
AS
$$
select t.idx
from unnest(p_input) with ordinality as t(i, idx)
where t.i > p_to_check
order by t.idx
limit 1
$$
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
;
上面将使用数组中的值已经排序的事实。因此,按数组索引排序非常快。我不确定unnest()
在这种情况下是否保证按照它们存储在数组中的顺序返回元素。如果是这种情况,您可以删除 order by
并使其更快。
【讨论】:
谢谢 - 似乎工作。一件小事 - idx 是一个 bigint,所以需要重铸(或者函数只能返回一个大 int)【参考方案2】:我认为没有比您的解决方案更有效的解决方案,除非您为此编写专用的 C 函数。
存储大型数组通常会导致性能下降。
【讨论】:
以上是关于有序 postgresql 数组中大于 x 的最小值的位置(优化)的主要内容,如果未能解决你的问题,请参考以下文章