Postgres 函数 FOR IN SELECT LOOP 缩放

Posted

技术标签:

【中文标题】Postgres 函数 FOR IN SELECT LOOP 缩放【英文标题】:Postgres function FOR IN SELECT LOOP scaling 【发布时间】:2020-02-11 04:50:33 【问题描述】:

我试图了解循环在 postgres 函数中的实际工作方式。

问题是,当使用这样的 SELECT 查询运行 FOR LOOP 时:

FOR v_tmp_pk IN SELECT user_pk
                        FROM users_table
                        WHERE enterprise_id = in_enterprise_id
                            AND
                             category_id = in_category_id
                            AND status = 0 ORDER BY user_pk LOOP

查询的所有结果是一次加载还是分页并返回,就像psql 会返回它们?实际的 FOR LOOP 将运行少量迭代,然后退出。

(...)
DECLARE
        v_user_pks int[];
        v_tmp_pk int;
BEGIN


FOR v_tmp_pk IN SELECT user_pk
                        FROM users_table
                        WHERE enterprise_id = in_enterprise_id
                            AND
                             category_id = in_category_id
                            AND status = 0 ORDER BY user_pk LOOP

    -- Try to get a lock on the record
    IF pg_try_advisory_xact_lock(v_tmp_pk) THEN

        -- Push in the array we are tracking
        v_user_pks = array_append(v_user_pks, v_tmp_pk);
    end if;

    -- If we have collected enough records, then come out of the loop
   EXIT WHEN array_length(v_user_pks, 1) = in_count;
end loop;

-- Do more things
(...)

我试图了解这种类型的循环将如何扩展。性能有何不同 - 如果要查询的表有 100 个有效结果而不是 100 万个结果。

它会一次加载所有结果,然后对其进行迭代,还是分块进行迭代?

【问题讨论】:

【参考方案1】:

PostgreSQL 在内部使用游标来处理这样的循环。这意味着结果是逐行计算的,没有内部缓冲区溢出的危险。

【讨论】:

以上是关于Postgres 函数 FOR IN SELECT LOOP 缩放的主要内容,如果未能解决你的问题,请参考以下文章

postgres 查询返回记录集的函数

Postgres:SELECT FOR UPDATE 在锁定释放后看不到新行

使用 Postgres 函数作为 ActiveRecord 模型

postgres in查询优化

如何从postgres函数返回两个SELECT语句的结果?

Postgres NOT IN 不工作