(Probably a duplicate but I can only find questions and solutions with the JOIN [3]
and that's not an option.)
I have two tables. Both very thin (few columns) and very long (many rows). One is the data table (articles
) and one is the ACL table (acl
).
I want to show only the articles I have access to via acl.some_id
. Which subquery is faster?
[1]
SELECT a.title
FROM articles a
WHERE 0 < (
SELECT COUNT(1)
FROM acl
WHERE article_id = a.id AND some_id IN (1, 2, 3)
)
or
[2]
SELECT a.title
FROM articles a
WHERE a.id IN (
SELECT article_id
FROM acl WHERE some_id IN (1, 2, 3)
)
My mind would say the second one, because that subquery can be reused for all potentially matching row, so will only be executed once (although the result set will be very large), while the subquery in the first will have to check for EVERY potentially matching row.
There's a third way, but that's not an option, because it would duplicate rows (and GROUP BY is not the solution because I need a COUNT for something else later (and DISTINCT is never a solution!)):
[3]
SELECT a.title
FROM articles a
JOIN acl
ON acl.article_id = a.id
WHERE acl.some_id IN (1, 2, 3)
Since article_id X exists N times in acl
, it would return that row 0 - N times instead of 0 - 1.
There's also a fourth way: EXISTS
. Thanks to ypercube.
Related: