Det er rigtigt, som det er blevet bemærket, at RETURNING
klausul af en INSERT
ser kun den indsatte række. Mere specifikt, citerer manualen her :
Fed min vægt.
Så intet forhindrer dig i at tilføje en korreleret underforespørgsel til RETURNING
liste:
Dette er også meget mere effektivt end den forespørgsel, du havde (eller det, der blev foreslået) af flere årsager.
-
Vi kører ikke underforespørgslerne
ee
ogep
over alle rækker i tabellernemedarbejdere.e-mails
ogemployees.profiles
. Det ville være effektivt, hvis vi havde brug for store dele af disse tabeller, men vi henter kun en enkelt række med interesse fra hver. Med passende indekser er en korreleret underforespørgsel meget mere effektiv til dette. Se: -
Vi tilføjer ikke overhead for en eller flere CTE'er.
-
Vi henter kun yderligere data efter en vellykket
INSERT
, så der spildes ingen tid, hvis indsatsen af en eller anden grund ikke gik igennem. (Se citat øverst!)
Plus, muligvis vigtigst, dette er korrekt . Vi bruger data fra rækken, der faktisk er blevet indsat - efter indsætter det. (Se citat øverst!) Efter mulige standardværdier er triggere eller regler blevet anvendt. Vi kan være sikre på, at det, vi ser, er det, der faktisk er i databasen (i øjeblikket).
Du har ingen ORDER BY
for profiler.navn_først
. Det er ikke rigtigt. Enten er der kun én kvalificerende række, så behøver vi ingen DISTINCT
heller ikke LIMIT 1
. Eller der kan være flere, så har vi også brug for en deterministisk ORDER BY
for at få et deterministisk resultat.
Og hvis emails.t
kan være NULL, skal du tilføje NULLS LAST
i ORDER BY
klausul. Se:
Indekser
Ideelt set har du disse indekser med flere kolonner (med kolonner i denne rækkefølge):
brugere (empl_user_pub_uuid, empl_user_pvt_uuid)
e-mails (empl_user_pvt_uuid, e-mail)
profiler (empl_user_pvt_uuid, name_first)
Så, hvis bordene er støvsuget nok, får du tre indeksscanninger, og hele operationen er lynhurtig.
Få præ-INSERT
værdier?
Hvis du virkelig ønsker det (hvilket jeg ikke tror, du gør), så overvej: