Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tags_count only need to join on the taggable's table if using STI #904

Merged
merged 1 commit into from
Jun 30, 2018

Conversation

hengwoon
Copy link

The INNER JOIN on the taggable's table name is only necessary if the taggable is using single table inheritance. Otherwise, the IN subquery generated in generate_tagging_scope_in_clause, which retrieves a list of the taggable's IDs based on the current scope, is sufficient. tagging_conditions also already includes making sure that taggable_type is the one that corresponds to the taggable.

The removal of the extra inner join in non-STI cases improves performance quite significantly for tag counts.

Take into consideration Project.tag_counts_on(:tags), and Project.where("client is not null").tag_counts_on(:tag)

Current:

SELECT  tags.*, taggings.tags_count AS count 
FROM "tags" 
JOIN (
  SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count 
  FROM "taggings" 
  INNER JOIN projects ON projects.id = taggings.taggable_id 
  WHERE (taggings.taggable_type = 'Project' AND taggings.context = 'tags') 
  AND (taggings.taggable_id IN(
    SELECT projects.id FROM "projects"
  )) 
  GROUP BY taggings.tag_id 
  HAVING COUNT(taggings.tag_id) > 0
) AS taggings ON taggings.tag_id = tags.id

SELECT  tags.*, taggings.tags_count AS count 
FROM "tags" 
JOIN (
  SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count 
  FROM "taggings" 
  INNER JOIN projects ON projects.id = taggings.taggable_id 
  WHERE (taggings.taggable_type = 'Project' AND taggings.context = 'tags') 
  AND (taggings.taggable_id IN(
    SELECT projects.id FROM "projects" where client is not null
  )) 
  GROUP BY taggings.tag_id 
  HAVING COUNT(taggings.tag_id) > 0
) AS taggings ON taggings.tag_id = tags.id

With this change:

SELECT  tags.*, taggings.tags_count AS count 
FROM "tags" 
JOIN (
  SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count 
  FROM "taggings"
  WHERE (taggings.taggable_type = 'Project' AND taggings.context = 'tags') 
  AND (taggings.taggable_id IN(
    SELECT projects.id FROM "projects"
  )) 
  GROUP BY taggings.tag_id 
  HAVING COUNT(taggings.tag_id) > 0
) AS taggings ON taggings.tag_id = tags.id

SELECT  tags.*, taggings.tags_count AS count 
FROM "tags" 
JOIN (
  SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count 
  FROM "taggings" 
  WHERE (taggings.taggable_type = 'Project' AND taggings.context = 'tags') 
  AND (taggings.taggable_id IN(
    SELECT projects.id FROM "projects" where client is not null
  )) 
  GROUP BY taggings.tag_id 
  HAVING COUNT(taggings.tag_id) > 0
) AS taggings ON taggings.tag_id = tags.id

Fixes #724

@hengwoon hengwoon changed the title We only need to join on the taggable's table if using STI tags_count only need to join on the taggable's table if using STI Jun 22, 2018
@seuros
Copy link
Collaborator

seuros commented Jun 25, 2018

Can you add a test case and the change log entry ?

@hengwoon
Copy link
Author

I've updated the changelog as well as added a test case and modified the version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants