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(),用于计算一个表中某一列的平均值。
在上述示例中,get_average() 函数是一个 STABLE 函数,它接受列名和表名作为输入参数,并通过动态执行 SQL 语句来计算平均值。如果我们在一个查询中多次调用 get_average() 函数,例如:
我们可能会发现 PostgreSQL 在查询计划中多次调用 get_average() 函数。这是因为 PostgreSQL 在解析查询计划时会考虑到函数的稳定性,并根据实际情况选择是否多次调用函数以提高性能。
IMMUTABLE 函数的示例
类似地,让我们通过一个示例来说明 IMMUTABLE 函数为何会被多次调用。假设我们有一个自定义函数 get_previous_date(),用于获取某个日期的前一天日期。
在上述示例中,get_previous_date() 函数是一个 IMMUTABLE 函数,它接受当前日期作为输入,并返回前一天的日期。如果我们在一个查询中多次调用 get_previous_date() 函数,例如:
我们可能会观察到 PostgreSQL 在查询计划中多次调用 get_previous_date() 函数。这是因为 PostgreSQL 在解析查询计划时会优化查询,包括对 IMMUTABLE 函数的调用次数进行优化。
为什么会多次调用 STABLE/IMMUTABLE 函数?
PostgreSQL 之所以多次调用 STABLE 或 IMMUTABLE 函数,是为了提高查询性能和优化查询计划。通过多次调用函数并缓存结果,可以减少函数调用的开销和提高查询的效率。尽管可能存在多次调用的情况,但这并不一定意味着函数的计算结果被多次执行。因此,即使函数被多次调用,相同的输入仍然只会计算一次。
总结
在本文中,我们介绍了 PostgreSQL 数据库为什么会多次调用声明为 STABLE 或 IMMUTABLE 的函数。我们了解了 STABLE 函数在同一事务内对相同的输入始终返回相同结果,而 IMMUTABLE 函数对于任何输入都会返回相同结果。了解了函数的分类及其调用方式后,我们知道 PostgreSQL 在查询计划中多次调用函数是为了提高查询性能和优化查询计划。尽管多次调用函数,但相同的输入只会计算一次,不会被多次执行。有了对这一特性的了解,我们可以更好地使用 PostgreSQL 数据库并优化查询性能。