EXISTS vs. JOINS pros and cons have been discussed over the time. I've seen some different arguments. Some say EXISTS is faster because when two joining tables are large, EXISTS reduces line joining by filter out unqualified rows. Some say they're about the same, because Postgres implement them in the same way underneath.

In order to test the performance, I ran some benchmarks to see the difference. Our app has huge sets of records and complicated sql statements. We're running through 6 tables, with records from 3 million rows to 73 million.

Here is the Postgres reported numbers.

With JOINS:

WindowAgg  (cost=2429100.35..2772390.11 rows=13411000 width=20)
   ->  Merge Left Join  (cost=2429100.35..2537697.61 rows=13411000 width=20)
........

With EXISTS:

WindowAgg  (cost=2389182.09..2724662.45 rows=13411000 width=20)
   ->  Merge Left Join  (cost=2389182.09..2489969.95 rows=13411000 width=20)
........

It looks like with EXISTS, it speeds up about 1.6%.