logic changing exists vs exists limit 1 logic changing exists vs exists limit 1 postgresql postgresql

logic changing exists vs exists limit 1


Based on those results, the high-level logic is not changed (the same, empty, set is returned in both cases) but the plan is changed resulting in a large performance difference.

What appears to be happening is that PostgreSQL understands and is happy to turn the first case (without the LIMIT inside the EXISTS) into a Nested Loop join, while in the second case (with the LIMIT inside the EXISTS), PostgreSQL doesn't know how to turn it into a join (due to the LIMIT) and implements it using the naive approach- doing a sequential scan across the table and running the sub-query for each and every row.

PostgreSQL understands how EXISTS works and it knows that it need only find a single row, adding the "LIMIT 1" isn't necessary and, as in this case, actually ends up being detrimental.

It's possible that PostgreSQL could be improved to realize that a LIMIT 1 inside of an EXISTS is just noise and should not be meaningful, but that would increase the amount of time required to plan queries and it's not immediately clear that such time would be well spent.