"First, the MERGE command performs a join from data_source to target_table_name producing zero or more candidate change rows. For each candidate change row, the status of MATCHED or NOT MATCHED is set just once, after which WHEN clauses are evaluated in the order specified. For each candidate change row, the first clause to evaluate as true is executed."
Anybody know more about this?
From lots of experience with SQL Server, I know that over there, MERGE is not more efficient, it's just syntactic sugar - and in fact it's buggy syntactic sugar, as there are some conditions where it doesn't handle concurrency properly.
I'm now interesting in hearing about other standard (what I have come to expect as standard) SQL that's not or only now available on Postgres?
From the docs "At scale, MERGE may introduce complicated concurrency issues or require advanced troubleshooting. As such, plan to thoroughly test any MERGE statement before deploying to production."
I dont know if its better in PQSQL , but they took their time, so maybe it is
That is rather an understatement. IIRC unless you are careful with transaction isolation levels and other options, a single MERGE statement can still deadlock against itself.
See https://michaeljswart.com/2021/08/what-to-avoid-if-you-want-... and the older page it links to, mongst many references to the problems you can encounter.
Though things are a fair amount better than they used to be, back in 2008 when MERGE was first introduced, with most of the persistent buggy behaviours pertaining to specific features that not everyone uses, I still completely avoid it.
We tried to use it for "upsert" type capabilities and even that would cause weird deadlocks.
Postgres already has the `Insert foo on conflict do update` type syntax which I think is generally better.
INSERT... ON CONFLICT is awesome, but it has some limitations.
The one I ran into most commonly is that it can only handle exactly one unique constraint on the target table. So if you have both a PK and another unique index, you need to choose which one gets the simple 'on conflict' and which one gets a hacky workaround (locks/transactions, triggers, exception handling, etc.)
If I'm reading the MERGE docs right, you can handle that case:
WHEN MATCHED AND old.pkey = new.pkey THEN UPDATE SET value = new.value
WHEN MATCHED AND old.col1 = new.col1 AND old.col2 = new.col2 THEN UPDATE SET reps = reps + 1
WHEN NOT MATCHED THEN INSERT [...]
edit: Postgres docs on MERGE: https://www.postgresql.org/docs/15/sql-merge.html