Feature #44252
openPreload journal details when retrieving Activity events to avoid N+1 queries
Description
The Activity view preloads the issue, project, tracker, and user for Journal events, but it does not preload Journal#details. Rendering event_title and event_type calls Journal#new_status, which accesses details and causes one JournalDetail Load query per journal event.
The existing join to journal_details is used for filtering and does not mark the association as loaded. This patch adds :details to the existing preload list, following the Activity view preload improvements in #42077.
The attached single patch is based on Redmine trunk r24810 (Git commit 98ac3ddd318acaad43a76c5f515598e87651ab6d).
Performance verification¶
Temporary journals and corresponding status-change details were added inside a transaction. The issues activity scope was retrieved, and the event properties used by the Activity view were accessed. Results are medians of three runs after a warm-up, with the Active Record query cache enabled. All temporary data was rolled back.
Environment: Redmine 6.1.3.devel, Ruby 3.4.7, Rails 8.1.3, SQLite 3.53.2.
| Journals added | Journal events | Total SQL before | Total SQL after | JournalDetail Load before |
JournalDetail Load after |
Median before | Median after |
|---|---|---|---|---|---|---|---|
| 100 | 105 | 121 | 17 | 105 | 1 | 92.2 ms | 97.3 ms |
| 500 | 505 | 521 | 17 | 505 | 1 | 385.5 ms | 345.4 ms |
| 1,000 | 1,005 | 1,021 | 17 | 1,005 | 1 | 776.0 ms | 654.3 ms |
| 5,000 | 5,005 | 5,021 | 17 | 5,005 | 1 | 3,905.4 ms | 3,286.9 ms |
Without the patch, JournalDetail Load queries increase linearly with the number of journal events. With the patch, they remain at one query. In the 5,000-record case, the median elapsed time was reduced by approximately 15.8%.
Test results¶
RAILS_ENV=test bundle exec rails test test/unit/activity_test.rb test/functional/activities_controller_test.rb 35 runs, 131 assertions, 0 failures, 0 errors, 0 skips
Files
No data to display