PERF: Avoid some more count queries when fetching more results
This commit is contained in:
parent
b8d1079e68
commit
11939fa8b9
|
@ -566,16 +566,8 @@ class Search
|
||||||
posts = posts.joins('JOIN users u ON u.id = posts.user_id')
|
posts = posts.joins('JOIN users u ON u.id = posts.user_id')
|
||||||
posts = posts.where("posts.raw || ' ' || u.username || ' ' || COALESCE(u.name, '') ilike ?", "%#{term_without_quote}%")
|
posts = posts.where("posts.raw || ' ' || u.username || ' ' || COALESCE(u.name, '') ilike ?", "%#{term_without_quote}%")
|
||||||
else
|
else
|
||||||
|
|
||||||
|
|
||||||
posts = posts.where("post_search_data.search_data @@ #{ts_query}")
|
posts = posts.where("post_search_data.search_data @@ #{ts_query}")
|
||||||
|
|
||||||
min_id = Search.min_post_id
|
|
||||||
if min_id > 0
|
|
||||||
fast_query = posts.dup.where("post_search_data.post_id >= #{min_id}")
|
|
||||||
posts = fast_query if fast_query.dup.count >= 50
|
|
||||||
end
|
|
||||||
|
|
||||||
exact_terms = @term.scan(/"([^"]+)"/).flatten
|
exact_terms = @term.scan(/"([^"]+)"/).flatten
|
||||||
exact_terms.each do |exact|
|
exact_terms.each do |exact|
|
||||||
posts = posts.where("posts.raw ilike ?", "%#{exact}%")
|
posts = posts.where("posts.raw ilike ?", "%#{exact}%")
|
||||||
|
@ -687,34 +679,51 @@ class Search
|
||||||
@ts_query_cache[(locale || query_locale) + " " + @term] ||= Search.ts_query(@term, locale)
|
@ts_query_cache[(locale || query_locale) + " " + @term] ||= Search.ts_query(@term, locale)
|
||||||
end
|
end
|
||||||
|
|
||||||
def aggregate_search(opts = {})
|
def wrap_rows(query)
|
||||||
|
"SELECT *, row_number() over() row_number FROM (#{query.to_sql}) xxx"
|
||||||
|
end
|
||||||
|
|
||||||
|
def aggregate_post_sql(opts)
|
||||||
min_or_max = @order == :latest ? "max" : "min"
|
min_or_max = @order == :latest ? "max" : "min"
|
||||||
|
|
||||||
post_sql =
|
query =
|
||||||
if @order == :likes
|
if @order == :likes
|
||||||
# likes are a pain to aggregate so skip
|
# likes are a pain to aggregate so skip
|
||||||
posts_query(@limit, private_messages: opts[:private_messages])
|
posts_query(@limit, private_messages: opts[:private_messages])
|
||||||
.select('topics.id', "post_number")
|
.select('topics.id', "post_number")
|
||||||
.to_sql
|
|
||||||
else
|
else
|
||||||
posts_query(@limit, aggregate_search: true,
|
posts_query(@limit, aggregate_search: true, private_messages: opts[:private_messages])
|
||||||
private_messages: opts[:private_messages])
|
|
||||||
.select('topics.id', "#{min_or_max}(post_number) post_number")
|
.select('topics.id', "#{min_or_max}(post_number) post_number")
|
||||||
.group('topics.id')
|
.group('topics.id')
|
||||||
.to_sql
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
min_id = Search.min_post_id
|
||||||
|
if min_id > 0
|
||||||
|
low_set = query.dup.where("post_search_data.post_id < #{min_id}")
|
||||||
|
high_set = query.where("post_search_data.post_id >= #{min_id}")
|
||||||
|
|
||||||
|
return { default: wrap_rows(high_set), remaining: wrap_rows(low_set) }
|
||||||
|
end
|
||||||
|
|
||||||
# double wrapping so we get correct row numbers
|
# double wrapping so we get correct row numbers
|
||||||
post_sql = "SELECT *, row_number() over() row_number FROM (#{post_sql}) xxx"
|
{ default: wrap_rows(query) }
|
||||||
|
end
|
||||||
|
|
||||||
posts = Post.includes(:topic => :category)
|
def aggregate_posts(post_sql)
|
||||||
.includes(:user)
|
return [] unless post_sql
|
||||||
.joins("JOIN (#{post_sql}) x ON x.id = posts.topic_id AND x.post_number = posts.post_number")
|
|
||||||
.order('row_number')
|
|
||||||
|
|
||||||
posts.each do |post|
|
Post.includes(:topic => :category)
|
||||||
@results.add(post)
|
.includes(:user)
|
||||||
|
.joins("JOIN (#{post_sql}) x ON x.id = posts.topic_id AND x.post_number = posts.post_number")
|
||||||
|
.order('row_number')
|
||||||
|
end
|
||||||
|
|
||||||
|
def aggregate_search(opts = {})
|
||||||
|
post_sql = aggregate_post_sql(opts)
|
||||||
|
|
||||||
|
aggregate_posts(post_sql[:default]).each {|p| @results.add(p)}
|
||||||
|
if @results.posts.size < @limit
|
||||||
|
aggregate_posts(post_sql[:remaining]).each {|p| @results.add(p) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue