Home > Database > Mysql Tutorial > How Can I Avoid Multiple Function Evaluations When Using `(func()).*` in PostgreSQL?

How Can I Avoid Multiple Function Evaluations When Using `(func()).*` in PostgreSQL?

DDD
Release: 2025-01-10 11:19:42
Original
454 people have browsed it

How Can I Avoid Multiple Function Evaluations When Using `(func()).*` in PostgreSQL?

*Avoid using `(func()).` in PostgreSQL to cause repeated function calls**

In PostgreSQL, using the (func()).* syntax to access the results of a function that returns a table or composite type may result in repeated calls to the function for each column. This can impact performance, especially if the function is computationally expensive.

Solution

To avoid this problem, you can wrap the function call in a subquery like this:

<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>
Copy after login
Copy after login

This ensures that the function is called only once, regardless of how many columns are in the result. Alternatively, in PostgreSQL 9.3 and later, you can use the LATERAL JOIN syntax:

<code class="language-sql">SELECT mf.*
FROM some_table
LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>
Copy after login

Cause of the problem

The repeated call occurs because the parser treats (func()).* as a placeholder for a list of column names. It expands the expression macro into a series of separate columns, resulting in multiple calls to the function.

Demo

To demonstrate the problem and solution, create a function:

<code class="language-sql">CREATE OR REPLACE FUNCTION my_func(integer)
RETURNS TABLE(a integer, b integer, c integer) AS $$
BEGIN
    RAISE NOTICE 'my_func(%)',;
    RETURN QUERY SELECT , , ;
END;
$$ LANGUAGE plpgsql;</code>
Copy after login

and a table containing dummy data:

<code class="language-sql">CREATE TABLE some_table AS SELECT x FROM generate_series(1,10) x;</code>
Copy after login

Compare the results of the following queries:

  • Original syntax:
<code class="language-sql">SELECT (my_func(x)).* FROM some_table;</code>
Copy after login
  • Solution syntax:
<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>
Copy after login
Copy after login

You'll notice that the original syntax raises multiple notifications, while the solution syntax only raises one notification, demonstrating the effect of avoiding multiple function calls.

The above is the detailed content of How Can I Avoid Multiple Function Evaluations When Using `(func()).*` in PostgreSQL?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template