Improve the fact_values api performance when loading a large number of facts
This is due to the current way the build_facts_hash method is implemented, leading to a lot of excessive memory load, and some unneeded preloads from the db.
Fixes #34160 - Improve fact_values api performance
Previously, the fact_values api called loaded a lot of un-needed data
from the database and used a sub-optimal way of converting the data to a
hash for display.
This commit changes the implementations so that we only load the
required columns from the database and generate the hash in a much more
efficient way. It also moves the build_facts_hash method from FactValue
model to the controller, which is its only consumer.
Before, loading 20 facts (default per_page setting):
Completed 200 OK in 52ms (Views: 2.6ms | ActiveRecord: 15.5ms | Allocations: 35603)
Before, loading 1000 facts:
Completed 200 OK in 1181ms (Views: 2.2ms | ActiveRecord: 22.8ms | Allocations: 1390471)
Before, loading 10000 facts:
Completed 200 OK in 14581ms (Views: 7.4ms | ActiveRecord: 75.6ms | Allocations: 22283568)
After, loading 20 facts:
Completed 200 OK in 37ms (Views: 3.8ms | ActiveRecord: 18.3ms | Allocations: 15549)
After, loading 1000 facts:
Completed 200 OK in 53ms (Views: 2.4ms | ActiveRecord: 16.0ms | Allocations: 47083)
After, loading 10000 facts:
Completed 200 OK in 313ms (Views: 5.8ms | ActiveRecord: 38.7ms | Allocations: 433106)