PostgreSQL 为什么会多次调用我的 STABLE/IMMUTABLE 函数

PostgreSQL 为什么会多次调用我的 STABLE/IMMUTABLE 函数

在本文中,我们将介绍为什么 PostgreSQL 数据库会多次调用一个声明为 STABLE 或者 IMMUTABLE 的函数。首先,我们需要理解 STABLE 和 IMMUTABLE 函数的含义。

阅读更多:PostgreSQL 教程

STABLE 和 IMMUTABLE 函数是什么?

PostgreSQL 中,函数可以分为三个不同的类别:VOLATILE、STABLE 和 IMMUTABLE。VOLATILE 函数是指在每次调用时都可能返回不同结果的函数,例如随机数生成函数。STABLE 函数是指在同一事务内,对于相同的输入,始终返回相同的结果。IMMUTABLE 函数是指对于任何输入,在任何情况下都会返回相同的结果,即函数的输出不受输入的影响。

为了提高查询的性能,PostgreSQL 会缓存函数的结果。对于 VOLATILE 函数,每次调用都会重新计算和缓存结果。而对于 STABLE 和 IMMUTABLE 函数,PostgreSQL 会在查询中的不同位置多次调用函数,但仅在第一次调用时计算和缓存结果。这就是为什么在某些情况下,我们会观察到 PostgreSQL 多次调用 STABLE 或 IMMUTABLE 函数的原因。

STABLE 函数的示例

让我们通过一个示例来说明 STABLE 函数为何会被多次调用。假设我们有一个自定义函数 get_average(),用于计算一个表中某一列的平均值。

CREATE OR REPLACE FUNCTION get_average(col_name text, table_name text)
RETURNS numeric AS DECLARE
    avg_value numeric;
BEGIN
    EXECUTE format('SELECT AVG(%I) FROM %I', col_name, table_name) INTO avg_value;
    RETURN avg_value;
END; LANGUAGE plpgsql STABLE;
SQL

在上述示例中,get_average() 函数是一个 STABLE 函数,它接受列名和表名作为输入参数,并通过动态执行 SQL 语句来计算平均值。如果我们在一个查询中多次调用 get_average() 函数,例如:

SELECT get_average('score', 'students') FROM students_data;
SQL

我们可能会发现 PostgreSQL 在查询计划中多次调用 get_average() 函数。这是因为 PostgreSQL 在解析查询计划时会考虑到函数的稳定性,并根据实际情况选择是否多次调用函数以提高性能。

IMMUTABLE 函数的示例

类似地,让我们通过一个示例来说明 IMMUTABLE 函数为何会被多次调用。假设我们有一个自定义函数 get_previous_date(),用于获取某个日期的前一天日期。

CREATE OR REPLACE FUNCTION get_previous_date(current_date date)
RETURNS date AS DECLARE
    previous_date date;
BEGIN
    previous_date := current_date - interval '1 day';
    RETURN previous_date;
END; LANGUAGE plpgsql IMMUTABLE;
SQL

在上述示例中,get_previous_date() 函数是一个 IMMUTABLE 函数,它接受当前日期作为输入,并返回前一天的日期。如果我们在一个查询中多次调用 get_previous_date() 函数,例如:

SELECT get_previous_date('2022-01-01') FROM generate_series('2022-02-01'::date, '2022-02-28'::date, '1 day');
SQL

我们可能会观察到 PostgreSQL 在查询计划中多次调用 get_previous_date() 函数。这是因为 PostgreSQL 在解析查询计划时会优化查询,包括对 IMMUTABLE 函数的调用次数进行优化。

为什么会多次调用 STABLE/IMMUTABLE 函数?

PostgreSQL 之所以多次调用 STABLE 或 IMMUTABLE 函数,是为了提高查询性能和优化查询计划。通过多次调用函数并缓存结果,可以减少函数调用的开销和提高查询的效率。尽管可能存在多次调用的情况,但这并不一定意味着函数的计算结果被多次执行。因此,即使函数被多次调用,相同的输入仍然只会计算一次。

总结

在本文中,我们介绍了 PostgreSQL 数据库为什么会多次调用声明为 STABLE 或 IMMUTABLE 的函数。我们了解了 STABLE 函数在同一事务内对相同的输入始终返回相同结果,而 IMMUTABLE 函数对于任何输入都会返回相同结果。了解了函数的分类及其调用方式后,我们知道 PostgreSQL 在查询计划中多次调用函数是为了提高查询性能和优化查询计划。尽管多次调用函数,但相同的输入只会计算一次,不会被多次执行。有了对这一特性的了解,我们可以更好地使用 PostgreSQL 数据库并优化查询性能。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册