Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Performance tunning on tagged_with(:any => true) #112

Merged
merged 4 commits into from

4 participants

@rpanachi

I made a little change in method tagged_with when supplied :any => true, to use JOIN instead of IN to compose the fetch query, in order to improve its performance. With a few tests in my real application, a query that took ~ 6.5 seconds was reduced to ~ 0.2 seconds, after change. Please consider to merge the changes with main repository so I can use it on my application. Any questions or suggestions, please contact me. Tks

@MyHealthTeams

This sounds pretty good. I wonder why it has been outstanding for so long.

@rpanachi

insiderpages, me too.

@pbalduino

mbleigh is giving a shit for any improvement.
Open source my ass.

@nhessler nhessler merged commit 7040626 into mbleigh:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 15 additions and 5 deletions.
  1. +15 −5 lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
View
20 lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
@@ -80,8 +80,18 @@ def tagged_with(tags, options = {})
conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
elsif options.delete(:any)
- tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
- conditions << "#{table_name}.#{primary_key} IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
+ conditions << tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name LIKE ?", t]) }.join(" OR ")
+
+ tagging_join = " JOIN #{ActsAsTaggableOn::Tagging.table_name}" +
+ " ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{table_name}.#{primary_key}" +
+ " AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}" +
+ " JOIN #{ActsAsTaggableOn::Tag.table_name}" +
+ " ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.id"
+
+ tagging_join << " AND " + sanitize_sql(["#{ActsAsTaggableOn::Tagging.table_name}.context = ?", context.to_s]) if context
+ select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
+
+ joins << tagging_join
else
tags = ActsAsTaggableOn::Tag.named_any(tag_list)
@@ -115,8 +125,8 @@ def tagged_with(tags, options = {})
group = "#{group_columns} HAVING COUNT(#{taggings_alias}.taggable_id) = #{tags.size}"
end
-
- scoped(:joins => joins.join(" "),
+ scoped(:select => select_clause,
+ :joins => joins.join(" "),
:group => group,
:conditions => conditions.join(" AND "),
:order => options[:order],
@@ -249,4 +259,4 @@ def save_tags
end
end
end
-end
+end
Something went wrong with that request. Please try again.