I was able to reproduce the problem and confirm, that the patch, provided above, is improving the performance.
First a problem recap and how to reproduce it:
The way TimeEntryActivity
works: you create them in 'Administration|Enumerations|Activities'
and change them per project in 'Project|Settings|Time Tracing'
.
The important thing: only when something is changed in per project settings, new DB record is created. So even with a lot of activities and projects, there will be no visible problem, if there are no changes.
To create the test setup, a script, provided by Mr. Mizuki Ishikawa (the patch author) was used:
70.times do |n|
TimeEntryActivity.create!(name: "TimeEntryActivity#{n}")
end
100.times do |n|
project = Project.create!(name: "Project#{n}", identifier: "project-#{n}")
project.set_parent!(nil)
project.update_or_create_time_entry_activities(
TimeEntryActivity.where(project_id: nil).map do |t|
[
t.id.to_s, {
"parent_id" => t.id.to_s,
"active" => "0",
"custom_field_values" => {"7" => "0"}
}
]
end.to_h
)
end
A small warning: Apply the patch before running the script and then remove it, if needed, for the tests. Without the patch it is taking very long time to create the DB records. Which already is a prove for patch effectiveness.
The way to introduce a lot of changes is from 'Project|Settings|Time tracking'
to first click 'Reset'
and then manually change all the activities. Then click 'Save' button and check how long it takes to save the changes.
I tested with 100 and with 200 projects. Results from my tests (local PostgreSQL DB, running in Docker container, Redmine-4.1.1):
- no patch, 70 activities, 100 projects: ~35sec
- no patch, 70 activities, 200 projects: ~50sec
- with patch, 70 activities, 200 projects: ~2-3sec
As you can see increasing the number of projects increase the time of saving. So it is possible, as Mr. Shigeo Teraoka reported, with 800 projects this time to be more then 5 min.
And as you can see applying the patch will reduce that time significantly.