1

I have so-called links that can have tags assigned to them, so I store it in 3 tables:

  • tag: id, name
  • tag_in_link: tag_id, link_id
  • link: id, url

Now I need to get basic tag counts: how many times a tag was used (including 0 times). I have two queries:

select t.id, t.name, count(*)
from tag as t inner join tag_in_link as tl
    on tl.tag_id = t.id
group by t.id, t.name
union
select t.id, t.name, 0
from tag as t left outer join tag_in_link as tl
    on tl.tag_id = t.id where tl.tag_id is null

union of joins explained

and

select t.id, t.name,
       (select count(*) from tag_in_link as tl
              where tl.tag_id = t.id
       ) as count from tag as t

correlated subquery

they both give the same (up to the order of records) results and work almost as fast

Problem is that I don't have much data to test it, but I need to pick one way or another today. All I know is that, there will be:

  • up to 100 tags
  • millions of links

So my question:

  • which approach : a dependent subquery or union of joins has better performance on large tables in postgres?
1
  • Could you show explain for both queries? Commented Jan 7, 2018 at 17:07

2 Answers 2

1

The first query will be better for large data sets, because it does not force a nested loop.

But why don't you use the optimal query:

SELECT t.id, t.name, count(*)
FROM tag AS t LEFT JOIN tag_in_link AS tl
    ON tl.tag_id = t.id
GROUP BY t.id, t.name;
Sign up to request clarification or add additional context in comments.

2 Comments

this query doesn't give me 0 counts, which i need
Sorry, I used an inner join instead of a left join. Fixed.
0

Consider combining UNION with a conditional aggregation, still avoiding the correlated subquery run for every row.

select t.id, t.name, 
       sum(case when tl.tag_id is null then 0 else 1 end) as tag_count
from tag as t 
left join tag_in_link as tl
    on tl.tag_id = t.id
group by t.id, t.name

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.