0

I have this simple query that finds all transactions from accounts belonging to a specific login, with some extra conditions on the transactions.

SELECT t.id, t.date, t.amount, t.description FROM transaction t
INNER JOIN account ac ON t.account = ac.id AND ac.login_id = ${loginId}
WHERE t.processed = false AND t.updated_by_user = false
AND t.category = 'uncategorized' ;

Will this query perform faster with a subquery on accounts, for example:

SELECT t.id, t.date, t.amount, t.description FROM transaction t
INNER JOIN (SELECT id FROM account WHERE login_id = ${loginId}) ac ON t.account = ac.id
WHERE t.processed = false AND t.updated_by_user = false
AND t.category = 'uncategorized' ;

I'd appreciate some insightful comments on this, thanks in advance!

2
  • 1
    Why don't you check on your own system (with your disks, RAM and CPU) by running EXPLAIN on both? You could also do some timings
    – Vérace
    Commented Jul 18, 2016 at 5:52
  • 3
    I'm pretty sure Postgres' query optimizer is smart enough to use the same execution plan for both statements. You can use explain (analyze, verbose) select ... to verify that (but remember to run each statement several times to exclude the caching effects from the timing).
    – user1822
    Commented Jul 18, 2016 at 6:18

3 Answers 3

1

Use the INNER JOIN whenever possible because it's easier to read. It otherwise should not make a difference.

-1

you can also use cte's:

    with definitely_better as (SELECT id FROM account WHERE login_id = ${loginId}) 

    SELECT t.id, t.date, t.amount, t.description FROM transaction t
    INNER JOIN definitely better ac ON t.account = ac.id
    WHERE t.processed = false AND t.updated_by_user = false
    AND t.category = 'uncategorized' ;
4
  • 2
    CTEs might behave differently than the OP's queries, depending on version of Postgres Commented May 12, 2021 at 22:27
  • Is there any advantage to this? Commented Nov 4, 2022 at 14:35
  • @DavidAldridge performance wise, no. sytle wise, hell yea lol. If you want more performance, after three or four cte's you've normally got to convert them to temp tables.
    – James
    Commented Nov 5, 2022 at 16:20
  • The style is a matter of opinion, and I'd avoid them CTEs in earlier versions of PostgreSQL as they are an optimiser fence. Commented Nov 6, 2022 at 21:08
-1

You need to be careful on how you gauge performance with sub query vs inner join. Your query optimizer might build cache towards it and give you false speeds. As if you run this from a stored procedure it may not use the cache the same way as you running via your session.

However, I think between subquery, inner join or CTE, I would use inner join for this case. CTE for huge table data sets that require multiple data sets returned and combined. Subqueries I would try to avoid whenever possible in most cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.