This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/spec/components
Alan Guo Xiang Tan cd64e88711
PERF: Improve database query perf when loading topics for a category. (#14416)
* PERF: Improve database query perf when loading topics for a category.

Instead of left joining the `topics` table against `categories` by filtering with `categories.id`,
we can improve the query plan by filtering against `topics.category_id`
first before joining which helps to reduce the number of rows in the
topics table that has to be joined against the other tables and also
make better use of our existing index.

The following is a before and after of the query plan for a category
with many subcategories.

Before:

```
                                                                                                       QUERY PLAN

-------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
 Limit  (cost=1.28..747.09 rows=30 width=12) (actual time=85.502..2453.727 rows=30 loops=1)
   ->  Nested Loop Left Join  (cost=1.28..566518.36 rows=22788 width=12) (actual time=85.501..2453.722 rows=30 loops=1)
         Join Filter: (category_users.category_id = topics.category_id)
         Filter: ((topics.category_id = 11) OR (COALESCE(category_users.notification_level, 1) <> 0) OR (tu.notification_level > 1))
         ->  Nested Loop Left Join  (cost=1.00..566001.58 rows=22866 width=20) (actual time=85.494..2453.702 rows=30 loops=1)
               Filter: ((COALESCE(tu.notification_level, 1) > 0) AND ((topics.category_id <> 11) OR (topics.pinned_at IS NULL) OR ((t
opics.pinned_at <= tu.cleared_pinned_at) AND (tu.cleared_pinned_at IS NOT NULL))))
               Rows Removed by Filter: 1
               ->  Nested Loop  (cost=0.57..528561.75 rows=68606 width=24) (actual time=85.472..2453.562 rows=31 loops=1)
                     Join Filter: ((topics.category_id = categories.id) AND ((categories.topic_id <> topics.id) OR (categories.id = 1
1)))
                     Rows Removed by Join Filter: 13938306
                     ->  Index Scan using index_topics_on_bumped_at on topics  (cost=0.42..100480.05 rows=715549 width=24) (actual ti
me=0.010..633.015 rows=464623 loops=1)
                           Filter: ((deleted_at IS NULL) AND ((archetype)::text <> 'private_message'::text))
                           Rows Removed by Filter: 105321
                     ->  Materialize  (cost=0.14..36.04 rows=30 width=8) (actual time=0.000..0.002 rows=30 loops=464623)
                           ->  Index Scan using categories_pkey on categories  (cost=0.14..35.89 rows=30 width=8) (actual time=0.006.
.0.040 rows=30 loops=1)
                                 Index Cond: (id = ANY ('{11,53,57,55,54,56,112,94,107,115,116,117,97,95,102,103,101,105,99,114,106,1
13,104,98,100,96,108,109,110,111}'::integer[]))
               ->  Index Scan using index_topic_users_on_topic_id_and_user_id on topic_users tu  (cost=0.43..0.53 rows=1 width=16) (a
ctual time=0.004..0.004 rows=0 loops=31)
                     Index Cond: ((topic_id = topics.id) AND (user_id = 1103877))
         ->  Materialize  (cost=0.28..2.30 rows=1 width=8) (actual time=0.000..0.000 rows=0 loops=30)
               ->  Index Scan using index_category_users_on_user_id_and_last_seen_at on category_users  (cost=0.28..2.29 rows=1 width
=8) (actual time=0.004..0.004 rows=0 loops=1)
                     Index Cond: (user_id = 1103877)
 Planning Time: 1.359 ms
 Execution Time: 2453.765 ms
(23 rows)
```

After:

```
                                                                                                                            QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=1.28..438.55 rows=30 width=12) (actual time=38.297..657.215 rows=30 loops=1)
   ->  Nested Loop Left Join  (cost=1.28..195944.68 rows=13443 width=12) (actual time=38.296..657.211 rows=30 loops=1)
         Filter: ((categories.topic_id <> topics.id) OR (topics.category_id = 11))
         Rows Removed by Filter: 29
         ->  Nested Loop Left Join  (cost=1.13..193462.59 rows=13443 width=16) (actual time=38.289..657.092 rows=59 loops=1)
               Join Filter: (category_users.category_id = topics.category_id)
               Filter: ((topics.category_id = 11) OR (COALESCE(category_users.notification_level, 1) <> 0) OR (tu.notification_level > 1))
               ->  Nested Loop Left Join  (cost=0.85..193156.79 rows=13489 width=20) (actual time=38.282..657.059 rows=59 loops=1)
                     Filter: ((COALESCE(tu.notification_level, 1) > 0) AND ((topics.category_id <> 11) OR (topics.pinned_at IS NULL) OR ((topics.pinned_at <= tu.cleared_pinned_at) AND (tu.cleared_pinned_at IS NOT NULL))))
                     Rows Removed by Filter: 1
                     ->  Index Scan using index_topics_on_bumped_at on topics  (cost=0.42..134521.06 rows=40470 width=24) (actual time=38.267..656.850 rows=60 loops=1)
                           Filter: ((deleted_at IS NULL) AND ((archetype)::text <> 'private_message'::text) AND (category_id = ANY ('{11,53,57,55,54,56,112,94,107,115,116,117,97,95,102,103,101,105,99,114,106,113,104,98,100,96,108,109,110,111}'::integer[])))
                           Rows Removed by Filter: 569895
                     ->  Index Scan using index_topic_users_on_topic_id_and_user_id on topic_users tu  (cost=0.43..1.43 rows=1 width=16) (actual time=0.003..0.003 rows=0 loops=60)
                           Index Cond: ((topic_id = topics.id) AND (user_id = 1103877))
               ->  Materialize  (cost=0.28..2.30 rows=1 width=8) (actual time=0.000..0.000 rows=0 loops=59)
                     ->  Index Scan using index_category_users_on_user_id_and_last_seen_at on category_users  (cost=0.28..2.29 rows=1 width=8) (actual time=0.004..0.004 rows=0 loops=1)
                           Index Cond: (user_id = 1103877)
         ->  Index Scan using categories_pkey on categories  (cost=0.14..0.17 rows=1 width=8) (actual time=0.001..0.001 rows=1 loops=59)
               Index Cond: (id = topics.category_id)
 Planning Time: 1.633 ms
 Execution Time: 657.255 ms
(22 rows)
```

* PERF: Optimize index on topics bumped_at.

Replace `index_topics_on_bumped_at` index with a partial index on `Topic#bumped_at` filtered by archetype since there is already another index that covers private topics.
2021-09-28 10:05:00 +08:00
..
auth FEATURE: Add global admin api key rate limiter (#12527) 2021-06-03 10:52:43 +01:00
common_passwords DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
concern FIX: Nil-filled CF arrays were not being deleted (#13518) 2021-06-25 11:34:51 +02:00
email FIX: Handle forwarded email quotes around Reply-To display name (#14384) 2021-09-20 16:26:18 +10:00
file_store FIX: Make sure S3 object headers are preserved on copy (#14302) 2021-09-10 12:59:51 +10:00
freedom_patches FIX: Ensure id sequences are not reset during db:migrate (#14184) 2021-08-30 12:31:22 +01:00
guardian FEATURE: Uppy direct S3 multipart uploads in composer (#14051) 2021-08-25 08:46:54 +10:00
highlight_js DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
imap FEATURE: Use group SMTP settings for sending user notification emails (initial) (#13220) 2021-06-03 14:47:32 +10:00
import DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
middleware FEATURE: Rate limit exceptions via ENV (#14033) 2021-08-13 12:00:23 -03:00
migration FIX: Allow post migrations using #change to carry out unsafe migration 2020-05-15 14:23:27 +08:00
plugin FEATURE: Add new plugin API to allow plugins to extend Site#categories (#13773) 2021-07-19 13:54:19 +08:00
pretty_text SPEC: 'lookup_upload_urls' method should use cdn url if available. 2019-10-14 12:57:33 +05:30
rate_limiter DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
scheduler DEV: reduce logging when no external id is specified 2020-04-08 12:42:28 +10:00
site_settings DEV: Isolate multisite specs (#13634) 2021-07-07 18:57:42 +02:00
stylesheet FIX: Order outputted theme stylesheets (#14133) 2021-08-25 09:37:07 +08:00
svg_sprite FIX: Issues with custom icons in themes (#13732) 2021-07-14 15:18:29 -04:00
theme_store FEATURE: Allow themes to specify modifiers in their about.json file (#9097) 2020-03-11 13:30:45 +00:00
validators FEATURE: Humanize file size error messages (#14398) 2021-09-22 07:59:45 +10:00
wizard FEATURE: Enable auto dark mode on new instances (#14208) 2021-09-02 14:55:38 -04:00
admin_confirmation_spec.rb Update rubocop to 2.3.1. 2020-07-24 17:19:21 +08:00
admin_user_index_query_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
archetype_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
cache_spec.rb FIX: ensures defined expired_in is passed from write to write_entry (#11622) 2021-01-04 10:34:44 +01:00
category_badge_spec.rb FIX: Correctly escape category description text (#8107) 2019-10-01 12:04:39 -04:00
composer_messages_finder_spec.rb FEATURE: Make allow_uploaded_avatars accept TL (#14091) 2021-08-24 10:46:28 +03:00
content_buffer_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
cooked_post_processor_spec.rb FEATURE: Humanize file size error messages (#14398) 2021-09-22 07:59:45 +10:00
crawler_detection_spec.rb FEATURE: Implement browser update in crawler view (#12448) 2021-03-22 19:41:42 +02:00
current_user_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
directory_helper_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
discourse_diff_spec.rb Escape values of HTML attributes 2021-08-10 10:25:15 -04:00
discourse_event_spec.rb DEV: Plugin API to add directory columns (#13440) 2021-06-22 13:00:04 -05:00
discourse_hub_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
discourse_plugin_registry_spec.rb DEV: Remove deprecated plugins variables importer (#12168) 2021-02-23 16:20:59 -05:00
discourse_redis_spec.rb DEV: Remove specs that are no longer relevant. 2020-06-23 12:09:04 +08:00
discourse_spec.rb DEV: Improve Ember CLI's bootstrap logic (#12792) 2021-04-23 10:24:42 -04:00
discourse_tagging_spec.rb FIX: Show required tags to staff by default and override limit (#13242) 2021-06-02 12:43:34 -04:00
discourse_updates_spec.rb FIX: Sort admin dashboard new updates by latest (#12146) 2021-02-19 11:03:36 -05:00
distributed_memoizer_spec.rb DEV: s/\$redis/Discourse\.redis (#8431) 2019-12-03 10:05:53 +01:00
distributed_mutex_spec.rb DEV: Improve flaky time-sensitive specs (#9141) 2020-03-10 22:13:17 +01:00
email_cook_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
email_updater_spec.rb FEATURE: add maximum limit for secondary emails (#12599) 2021-04-05 20:31:42 +05:30
enum_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
excerpt_parser_spec.rb FIX: Make Oneboxer#apply insert block Oneboxes correctly (#11449) 2020-12-14 17:49:37 +02:00
feed_element_installer_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
feed_item_accessor_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
file_helper_spec.rb DEV: properly clean up temp files in FileHelper spec 2019-05-28 11:33:08 +10:00
filter_best_posts_spec.rb DEV: Prefabrication (test optimization) (#7414) 2019-05-07 13:12:20 +10:00
final_destination_spec.rb FEATURE: Onebox can match engines based on the content_type (#13876) 2021-07-30 13:36:30 -04:00
flag_settings_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
gaps_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
global_path_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
guardian_spec.rb DEV: Remove the use of stubs. (#14142) 2021-08-25 13:25:01 +08:00
has_errors_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
hijack_spec.rb FIX: strip the trailing slash (/) of cors origins. (#10996) 2020-10-29 13:01:06 +11:00
html_prettify_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
html_to_markdown_spec.rb FIX: Hoisting linebreaks shouldn't fail for HTML5 elements (#14364) 2021-09-17 10:41:34 +02:00
image_sizer_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
inline_oneboxer_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
js_locale_helper_spec.rb FEATURE: Add English (UK) as locale (#11768) 2021-01-20 21:32:22 +01:00
json_error_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
letter_avatar_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
method_profiler_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
new_post_manager_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
new_post_result_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
oneboxer_spec.rb FEATURE: Censor Oneboxes (#12902) 2021-06-03 11:39:12 +10:00
onpdiff_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
pbkdf2_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
pinned_check_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
plain_text_to_markdown_spec.rb FIX: use URI.regexp to find URLs in plain text 2019-06-07 01:26:06 +02:00
post_action_creator_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
post_creator_spec.rb DEV: Ignore bookmarks.topic_id column and remove references to it in code (#14289) 2021-09-15 10:16:54 +10:00
post_destroyer_spec.rb DEV: Remove unncessary fabrication in tests. 2021-07-26 09:14:23 +08:00
post_locker_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
post_merger_spec.rb FIX: TL4 users cannot delete others posts (#13554) 2021-06-30 15:51:35 +03:00
post_revisor_spec.rb DEV: clarify the slow mode specs names (#13962) 2021-08-05 22:07:29 +04:00
presence_channel_spec.rb DEV: Introduce PresenceChannel API for core and plugin use 2021-08-27 16:26:06 +01:00
pretty_text_spec.rb FIX: Do not replace in mentions and hashtags (#14260) 2021-09-09 12:03:59 +03:00
promotion_spec.rb FIX: check if BasicBadge is enabled for TL1 welcome message (#13983) 2021-08-11 08:39:25 +10:00
quote_comparer_spec.rb DEV: Prefabrication (test optimization) (#7414) 2019-05-07 13:12:20 +10:00
rate_limiter_spec.rb No need to disable rate limiter after running tests (#13093) 2021-05-19 16:04:35 +04:00
redis_store_spec.rb DEV: Implement a faster Discourse.cache 2019-11-27 16:11:49 +11:00
retrieve_title_spec.rb FIX: increase chunk size to fetch title tag correctly (#14144) 2021-09-03 13:15:58 +05:30
rtl_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
s3_helper_spec.rb FIX: Make sure S3 object headers are preserved on copy (#14302) 2021-09-10 12:59:51 +10:00
s3_inventory_multisite_spec.rb DEV: Isolate multisite specs (#13634) 2021-07-07 18:57:42 +02:00
s3_inventory_spec.rb DEV: Isolate multisite specs (#13634) 2021-07-07 18:57:42 +02:00
score_calculator_spec.rb DEV: Prefabrication (test optimization) (#7414) 2019-05-07 13:12:20 +10:00
scss_checker_spec.rb PERF: Eager load Theme associations in Stylesheet Manager. 2021-06-21 11:06:58 +08:00
search_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
secure_session_spec.rb DEV: correct implementation of expiry api 2019-11-11 11:18:12 +11:00
site_icon_manager_spec.rb DEV: enable frozen string literal on all files 2019-05-13 09:31:32 +08:00
site_setting_extension_multisite_spec.rb DEV: Isolate multisite specs (#13634) 2021-07-07 18:57:42 +02:00
site_setting_extension_spec.rb DEV: Isolate multisite specs (#13634) 2021-07-07 18:57:42 +02:00
slug_spec.rb DEV: Correct typos and spelling mistakes (#12812) 2021-05-21 11:43:47 +10:00
spam_handler_spec.rb FIX: use allowlist and blocklist terminology (#10209) 2020-07-27 10:23:54 +10:00
suggested_topics_builder_spec.rb DEV: Default to skipping creating a topic when fabricating categories (#7976) 2019-08-06 11:26:54 +01:00
system_message_spec.rb FIX: TL2 promotion message and advance training (#10679) 2020-09-22 10:17:52 +10:00
text_cleaner_spec.rb FEATURE: Correctly convert topic title to uppercase and lowercase for Turkish default locale (#13115) 2021-05-24 18:13:30 +10:00
text_sentinel_spec.rb FIX: prevents exception when text input is nil (#12922) 2021-05-03 09:21:35 +02:00
theme_settings_manager_spec.rb DEV: use upload id to save in theme setting instead of URL. (#14341) 2021-09-16 07:58:53 +05:30
theme_settings_parser_spec.rb DEV: Don't user before(:all)/after(:all) (#13389) 2021-06-15 17:25:06 +02:00
timeline_lookup_spec.rb DEV: followup to 8edd2b38cb to use existing spec (#11830) 2021-01-25 12:04:27 +01:00
topic_creator_spec.rb FIX: Enforce tag group count validation before sending to review queue (#12728) 2021-04-19 09:43:50 +10:00
topic_publisher_spec.rb DEV: Improve flaky time-sensitive specs (#9141) 2020-03-10 22:13:17 +01:00
topic_query_spec.rb PERF: Improve database query perf when loading topics for a category. (#14416) 2021-09-28 10:05:00 +08:00
topic_retriever_spec.rb FEATURE: Stop checking referer for embeds (#13756) 2021-07-16 15:25:49 -03:00
topic_view_spec.rb FEATURE: Topic-level bookmarks (#14353) 2021-09-21 08:45:47 +10:00
topics_bulk_action_spec.rb FEATURE: Dismiss new and unread for PM inboxes. 2021-08-05 12:56:15 +08:00
trashable_spec.rb DEV: Upgrading Discourse to Zeitwerk (#8098) 2019-10-02 14:01:53 +10:00
trust_level_spec.rb DEV: use #frozen_string_literal: true on all spec 2019-04-30 10:27:42 +10:00
unread_spec.rb FEATURE: Add last visit indication to topic view page. (#13471) 2021-07-05 14:17:31 +08:00
url_helper_spec.rb FIX: errors loading secure uploads when secure uploads is disabled (#13047) 2021-06-08 13:25:51 -04:00
user_lookup_spec.rb REVERT "FIX: do not show private group flair on user avatars" (#13991) 2021-08-10 17:25:11 +05:30
user_name_suggester_spec.rb FIX: allow for final sigma in suggested usernames (#11540) 2020-12-23 08:51:36 +11:00
version_spec.rb DEV: Fix an apparently "too modern" git command (#10894) 2020-10-12 22:54:56 +02:00