CTE vs Function/trigger performance in Postgresql
-
06-02-2021 - |
Pregunta
I have a very long CTE query that I have shortened here for readability. But it tries to insert state, county, city, zipcode and street into their own tables and then insert their ID for inserting the address in the property table.
with tmpstate as (
insert
into
state ....on
conflict ( lower(state_code) ) do
update
set
state_code = excluded.state_code returning id,
state_code ),
tmpcounty as (
insert
into
..... on
conflict ( lower(county),
state_id ) do
update
set
county = excluded.county returning id,
county ),
tmpcity as (
insert
into
.....
values ( 'Sarasota',
(
select
id
from
tmpcounty
limit 1 ),
(
select
id
from
tmpstate
limit 1 ) ) on
conflict ( lower(city),
county_id,
state_id ) do
update
set
city = excluded.city returning id,
city ),
tmpzipcode as (
...... returning id,
zipcode ),
tmpstreet as (
.... ),
tmpproperty as(
insert
into
property (full_address,
street_address,
street_id,
city_id,
state_id,
zipcode_id,
county_id,
property_details )
values('ssss',
'ssss',
(
select
id
from
tmpstreet
limit 1),
(
select
id
from
tmpcity
limit 1),
(
select
id
from
tmpstate
limit 1),
(
select
id
from
tmpzipcode
limit 1),
(
select
id
from
tmpcounty
limit 1),
'{}') returning id)
select
id
from
property
limit 1
Would there be any performance gain if I create functions/triggers that insert the street, city, etc... and return their id if they exist instead of this long CTE query?
Solución
Running a big statement with its CTEs will be more efficient than running several small ones.
The only advantage of having a PL/pgSQL function for the individual inserts is that plans of statements are cached for the duration of the database session. But you can put your big statement into such a function if you want to make use of that.