Execution plan for functions in PostgreSQL - postgresql

If I change user-defined function (UDF) that is in use in another UDF will the PostgreSQL rebuild execution plan for both of them or only for changed one?

If a function is unchanged, the execution plans for all its queries should remain cached.
So only the execution plans for the function you changed will be recalculated.
You can use the SQL statement DISCARD PLANS to discard all cached plans.

Related

Does the shared buffer space in PostgreSQL cache index queries?

If I want to load test against a PostgreSQL table on an index. Will the shared buffer space or any other memory component that PostgreSQL use cache the data/query plan?
I found this resource but it didn't really answer my question:
https://www.postgresql.fastware.com/blog/back-to-basics-with-postgresql-memory-components
There is no shared memory area in PostgreSQL where plans are cached.
Normally, execution plans are not cached at all, they have to be generated again whenever a query is run.
There are two exceptions where execution plans are cached in a database session (but not across sessions):
The plans of prepared statements are cached.
The plans of SQL statements run from a PL/pgSQL funtions are cached (except for dynamic SQL executed with EXECUTE).

Are query execution plans stored anywhere in postgresql?

I am trying to figure out if PostgreSQL query execution plans are stored somewhere (possibly as complimentary to pg_stat_statements and pg_prepared_statements) in a way they are available for longer than the duration of the session. I understand that PREPARE does cache a sql statement in pg_prepared_statements, though the plan itself does not seem to be available in any view as far as I can tell.
I am not sure if there is a doc explaining the life cycle of a query plan for PostgreSQL but from what it sounds in the EXPLAIN documentation, PostgreSQL does not cache query plans at all. Is this accurate?
Thanks!
PostgreSQL has no shared storage for execution plans, so they cannot be reused across database sessions.
There are two ways to cache an execution plan within a session:
Use prepared statements with the SQL statements PREPARE and EXECUTE. The plan will be cached for the life time of the prepared statement, usually until your session ends.
Use PL/pgSQL functions. The plans for all static SQL statements (that is, statements that are not run with EXECUTE) in such a function will be cached for the session life time.
Other than that, execution plans are not cached in PostgreSQL.

Why is not possible to use Commit and rollback in a PostgreSQL procedure?

I am creating procedures on a PostgreSQL database. I read about is not possible to use rollback inside these procedures.
Why?
Is it possible to use commit?
I guess that this is related with ACID properties, but what if we have two insert operations in a procedure. If the second fails the second one gets a rollback?
Thank you.
Postgres' overview gives a hint by explaining how their functions are different than traditional stored procedures:
Functions created with PL/pgSQL can be used anywhere that built-in functions could be used. For example, it is possible to create complex conditional computation functions and later use them to define operators or use them in index expressions.
This makes it awkward to support transactions within functions for every possible situation. From the docs:
Functions and trigger procedures are always executed within a transaction established by an outer query... However, a block containing an EXCEPTION clause effectively forms a subtransaction that can be rolled back without affecting the outer transaction.
If you were to have two INSERTs in a function, the first can be wrapped in an EXCEPTION block to catch any errors and decide if the second should be executed.
You are correct. You cannot rollback transactions that were started prior to the procedure from within the procedure. In addition, a transaction cannot be created within the procedure either. You would receive this error:
ERROR: cannot begin/end transactions in PL/pgSQL
SQL state: 0A000
Hint: Use a BEGIN block with an EXCEPTION clause instead.
As this error states, and as Matt mentioned, you could use an exception block to essentially perform a rollback. From the help:
When an error is caught by an EXCEPTION clause, the local variables of the PL/pgSQL function remain as they were when the error occurred, but all changes to persistent database state within the block are rolled back.
Alternatively, you could call the procedure from within a transaction, and roll that back if necessary.

Postgres Prepared Transactions vs Prepared Statements

I'm fine tuning a Postgres database and I am about to set the maximun number of with prepared transactions with max_prepared_transactions.
The application uses a lot of prepared statements but not prepared transactions in the sense PREPARE name AS xyz.
My question is:
Is there a difference between prepared statements and prepared
transactions?
Does max_prepared_transactions affect prepared statements?
Yes. PREPARE TRANSACTION is used to initiate a two-phase transaction, which is generally used if you want to commit atomically to two databases at the same time.
Prepared statements relate to requesting the server to plan an SQL statement ahead of time, usually so that you can execute the statement multiple times without the overhead of planning it each time. See PREPARE.
The two are unrelated.
No, max_prepared_transactions does not affect prepared statements.

SQL. How to exclude a statement from Actual Exec Plan?

SQL 2008. I am running sproc from SQL Studio and when I try to get Actual Execution Plan it blows up the tempdb.
I narrowed the problem down to call to a row scalar function which is used on 700K rows table.
I deduced that SQL is trying to create 700K exec plans for that function and writes all the data to tempdb which has 3Gb free space..
I dont really need to see the plan for that function.
Can I explicitely exclude a statement from generation of exec plan?
You can't exclude it from a execution plan, other than removing the call from the query.
It does however, sound like a prime candidate to switch from a scalar UDF to an inline table UDF. Scalar UDFs can be a big cause of poor performance due to be run once per row in a query.
Have a read through this article which contains an example to demonstrate.