mirror of
https://github.com/discourse/discourse.git
synced 2025-01-19 17:02:45 +08:00
d8c796bc44
Previously, we would only take either the `MIN` or `MAX` for `post_number` during aggregation meaning that the ranking is not considered. ``` require 'benchmark/ips' Benchmark.ips do |x| x.config(time: 10, warmup: 2) x.report("current aggregate search query") do DB.exec <<~SQL SELECT "posts"."id", "posts"."user_id", "posts"."topic_id", "posts"."post_number", "posts"."raw", "posts"."cooked", "posts"."created_at", "posts"."updated_at", "posts"."reply_to_post_number", "posts"."reply_count", "posts"."quote_count", "posts"."deleted_at", "posts"."off_topic_count", "posts"."like_count", "posts"."incoming_link_count", "posts"."bookmark_count", "posts"."score", "posts"."reads", "posts"."post_type", "posts"."sort_order", "posts"."last_editor_id", "posts"."hidden", "posts"."hidden_reason_id", "posts"."notify_moderators_count", "posts"."spam_count", "posts"."illegal_count", "posts"."inappropriate_count", "posts"."last_version_at", "posts"."user_deleted", "posts"."reply_to_user_id", "posts"."percent_rank", "posts"."notify_user_count", "posts"."like_score", "posts"."deleted_by_id", "posts"."edit_reason", "posts"."word_count", "posts"."version", "posts"."cook_method", "posts"."wiki", "posts"."baked_at", "posts"."baked_version", "posts"."hidden_at", "posts"."self_edits", "posts"."reply_quoted", "posts"."via_email", "posts"."raw_email", "posts"."public_version", "posts"."action_code", "posts"."locked_by_id", "posts"."image_upload_id" FROM "posts" JOIN (SELECT *, row_number() over() row_number FROM (SELECT topics.id, min(posts.post_number) post_number FROM "posts" INNER JOIN "post_search_data" ON "post_search_data"."post_id" = "posts"."id" INNER JOIN "topics" ON "topics"."id" = "posts"."topic_id" AND ("topics"."deleted_at" IS NULL) LEFT JOIN categories ON categories.id = topics.category_id WHERE ("posts"."deleted_at" IS NULL) AND "posts"."post_type" IN (1, 2, 3, 4) AND (topics.visible) AND (topics.archetype <> 'private_message') AND (post_search_data.search_data @@ TO_TSQUERY('english', '''postgres'':*ABCD')) AND (categories.id NOT IN ( SELECT categories.id WHERE categories.search_priority = 1 ) ) AND ((categories.id IS NULL) OR (NOT categories.read_restricted)) GROUP BY topics.id ORDER BY MAX(( TS_RANK_CD( post_search_data.search_data, TO_TSQUERY('english', '''postgres'':*ABCD'), 1|32 ) * ( CASE categories.search_priority WHEN 2 THEN 0.6 WHEN 3 THEN 0.8 WHEN 4 THEN 1.2 WHEN 5 THEN 1.4 ELSE CASE WHEN topics.closed THEN 0.9 ELSE 1 END END ) ) ) DESC, topics.bumped_at DESC LIMIT 51 OFFSET 0) xxx) x ON x.id = posts.topic_id AND x.post_number = posts.post_number WHERE ("posts"."deleted_at" IS NULL) ORDER BY row_number; SQL end x.report("current aggregate search query with proper ranking") do DB.exec <<~SQL SELECT "posts"."id", "posts"."user_id", "posts"."topic_id", "posts"."post_number", "posts"."raw", "posts"."cooked", "posts"."created_at", "posts"."updated_at", "posts"."reply_to_post_number", "posts"."reply_count", "posts"."quote_count", "posts"."deleted_at", "posts"."off_topic_count", "posts"."like_count", "posts"."incoming_link_count", "posts"."bookmark_count", "posts"."score", "posts"."reads", "posts"."post_type", "posts"."sort_order", "posts"."last_editor_id", "posts"."hidden", "posts"."hidden_reason_id", "posts"."notify_moderators_count", "posts"."spam_count", "posts"."illegal_count", "posts"."inappropriate_count", "posts"."last_version_at", "posts"."user_deleted", "posts"."reply_to_user_id", "posts"."percent_rank", "posts"."notify_user_count", "posts"."like_score", "posts"."deleted_by_id", "posts"."edit_reason", "posts"."word_count", "posts"."version", "posts"."cook_method", "posts"."wiki", "posts"."baked_at", "posts"."baked_version", "posts"."hidden_at", "posts"."self_edits", "posts"."reply_quoted", "posts"."via_email", "posts"."raw_email", "posts"."public_version", "posts"."action_code", "posts"."locked_by_id", "posts"."image_upload_id" FROM "posts" JOIN (SELECT *, row_number() over() row_number FROM (SELECT subquery.topic_id id, (ARRAY_AGG(subquery.post_number))[1] post_number, MAX(subquery.rank) rank, MAX(subquery.bumped_at) bumped_at FROM (SELECT "posts"."id", "posts"."user_id", "posts"."topic_id", "posts"."post_number", "posts"."raw", "posts"."cooked", "posts"."created_at", "posts"."updated_at", "posts"."reply_to_post_number", "posts"."reply_count", "posts"."quote_count", "posts"."deleted_at", "posts"."off_topic_count", "posts"."like_count", "posts"."incoming_link_count", "posts"."bookmark_count", "posts"."score", "posts"."reads", "posts"."post_type", "posts"."sort_order", "posts"."last_editor_id", "posts"."hidden", "posts"."hidden_reason_id", "posts"."notify_moderators_count", "posts"."spam_count", "posts"."illegal_count", "posts"."inappropriate_count", "posts"."last_version_at", "posts"."user_deleted", "posts"."reply_to_user_id", "posts"."percent_rank", "posts"."notify_user_count", "posts"."like_score", "posts"."deleted_by_id", "posts"."edit_reason", "posts"."word_count", "posts"."version", "posts"."cook_method", "posts"."wiki", "posts"."baked_at", "posts"."baked_version", "posts"."hidden_at", "posts"."self_edits", "posts"."reply_quoted", "posts"."via_email", "posts"."raw_email", "posts"."public_version", "posts"."action_code", "posts"."locked_by_id", "posts"."image_upload_id", ( TS_RANK_CD( post_search_data.search_data, TO_TSQUERY('english', '''postgres'':*ABCD'), 1|32 ) * ( CASE categories.search_priority WHEN 2 THEN 0.6 WHEN 3 THEN 0.8 WHEN 4 THEN 1.2 WHEN 5 THEN 1.4 ELSE CASE WHEN topics.closed THEN 0.9 ELSE 1 END END ) ) rank, topics.bumped_at bumped_at FROM "posts" INNER JOIN "post_search_data" ON "post_search_data"."post_id" = "posts"."id" INNER JOIN "topics" ON "topics"."id" = "posts"."topic_id" AND ("topics"."deleted_at" IS NULL) LEFT JOIN categories ON categories.id = topics.category_id WHERE ("posts"."deleted_at" IS NULL) AND "posts"."post_type" IN (1, 2, 3, 4) AND (topics.visible) AND (topics.archetype <> 'private_message') AND (post_search_data.search_data @@ TO_TSQUERY('english', '''postgres'':*ABCD')) AND (categories.id NOT IN ( SELECT categories.id WHERE categories.search_priority = 1 ) ) AND ((categories.id IS NULL) OR (NOT categories.read_restricted))) subquery GROUP BY subquery.topic_id ORDER BY rank DESC, bumped_at DESC LIMIT 51 OFFSET 0) xxx) x ON x.id = posts.topic_id AND x.post_number = posts.post_number WHERE ("posts"."deleted_at" IS NULL) ORDER BY row_number; SQL end x.compare! end ``` ``` Warming up -------------------------------------- current aggregate search query 1.000 i/100ms current aggregate search query with proper ranking 1.000 i/100ms Calculating ------------------------------------- current aggregate search query 17.726 (± 0.0%) i/s - 178.000 in 10.045107s current aggregate search query with proper ranking 17.802 (± 0.0%) i/s - 178.000 in 10.002230s Comparison: current aggregate search query with proper ranking: 17.8 i/s current aggregate search query: 17.7 i/s - 1.00x (± 0.00) slower ``` |
||
---|---|---|
.. | ||
auth | ||
common_passwords | ||
concern | ||
file_store | ||
freedom_patches | ||
guardian | ||
highlight_js | ||
imap | ||
import | ||
middleware | ||
migration | ||
onebox/engine | ||
plugin | ||
pretty_text | ||
rate_limiter | ||
scheduler | ||
site_settings | ||
stylesheet | ||
svg_sprite | ||
theme_store | ||
validators | ||
wizard | ||
admin_confirmation_spec.rb | ||
admin_user_index_query_spec.rb | ||
archetype_spec.rb | ||
avatar_lookup_spec.rb | ||
cache_spec.rb | ||
category_badge_spec.rb | ||
composer_messages_finder_spec.rb | ||
content_buffer_spec.rb | ||
cooked_post_processor_spec.rb | ||
crawler_detection_spec.rb | ||
current_user_spec.rb | ||
directory_helper_spec.rb | ||
discourse_diff_spec.rb | ||
discourse_event_spec.rb | ||
discourse_hub_spec.rb | ||
discourse_plugin_registry_spec.rb | ||
discourse_redis_spec.rb | ||
discourse_spec.rb | ||
discourse_tagging_spec.rb | ||
discourse_updates_spec.rb | ||
distributed_memoizer_spec.rb | ||
distributed_mutex_spec.rb | ||
email_cook_spec.rb | ||
email_updater_spec.rb | ||
enum_spec.rb | ||
excerpt_parser_spec.rb | ||
feed_element_installer_spec.rb | ||
feed_item_accessor_spec.rb | ||
file_helper_spec.rb | ||
filter_best_posts_spec.rb | ||
final_destination_spec.rb | ||
flag_settings_spec.rb | ||
gaps_spec.rb | ||
global_path_spec.rb | ||
guardian_spec.rb | ||
has_errors_spec.rb | ||
hijack_spec.rb | ||
html_prettify_spec.rb | ||
html_to_markdown_spec.rb | ||
image_sizer_spec.rb | ||
inline_oneboxer_spec.rb | ||
js_locale_helper_spec.rb | ||
json_error_spec.rb | ||
letter_avatar_spec.rb | ||
method_profiler_spec.rb | ||
new_post_manager_spec.rb | ||
new_post_result_spec.rb | ||
oneboxer_spec.rb | ||
onpdiff_spec.rb | ||
pbkdf2_spec.rb | ||
pinned_check_spec.rb | ||
plain_text_to_markdown_spec.rb | ||
post_action_creator_spec.rb | ||
post_creator_spec.rb | ||
post_destroyer_spec.rb | ||
post_locker_spec.rb | ||
post_merger_spec.rb | ||
post_revisor_spec.rb | ||
pretty_text_spec.rb | ||
promotion_spec.rb | ||
quote_comparer_spec.rb | ||
rate_limiter_spec.rb | ||
redis_store_spec.rb | ||
retrieve_title_spec.rb | ||
rtl_spec.rb | ||
s3_helper_spec.rb | ||
s3_inventory_spec.rb | ||
score_calculator_spec.rb | ||
search_spec.rb | ||
secure_session_spec.rb | ||
site_icon_manager_spec.rb | ||
site_setting_extension_spec.rb | ||
slug_spec.rb | ||
spam_handler_spec.rb | ||
suggested_topics_builder_spec.rb | ||
system_message_spec.rb | ||
text_cleaner_spec.rb | ||
text_sentinel_spec.rb | ||
theme_settings_manager_spec.rb | ||
theme_settings_parser_spec.rb | ||
timeline_lookup_spec.rb | ||
topic_creator_spec.rb | ||
topic_publisher_spec.rb | ||
topic_query_spec.rb | ||
topic_retriever_spec.rb | ||
topic_view_spec.rb | ||
topics_bulk_action_spec.rb | ||
trashable_spec.rb | ||
trust_level_spec.rb | ||
unread_spec.rb | ||
url_helper_spec.rb | ||
user_name_suggester_spec.rb | ||
version_spec.rb |