I’m having performance issues with one of my actions, and think I’ve
narrowed it down to too many sql queries.
I have a form with ~60 lines, which takes ~6 sec to save, 60%+ of that
is db io. There’s 650+ lines of log data, most of which are
AR/queries.
The app is a simple dual entry book keeping thingy, and the form in
question contains a journal entry along with a partial for every
transaction line; i.e. debet/credit account X by Y.
My update method goes something like this:
-Manually start a transaction. Don’t want any single writes to go
through if things bork up.
-Try to load the entry. Make sure it belongs to the logged in client
and doesn’t belong to a closed period, then update it with
update_attributes.
-Or create a new entry if it couldn’t be found.
-Then iterate through param[:line].keys, i.e. line id’s. If the id is
found in a session variable, bulk update the line, otherwise create a
new one from params[:line][id] and add it to the entry.
-save! the entry
I believe a lot of the queries are related to validation. I have 3-4
validates_associated/validates_presence_of statements in the line
class, and these relations seem to get loaded whenever i do an update.
I’ve tried commenting out the validations. Things are faster, but the
relations still seem to get loaded on update? I define foreign key
constraints in the db, so can probably drop these, or? This still
leaves me at 1.5-2 sec of db traffic, though…
How about custom validations? How should i write something like “def
validate; self.errors.add(:entry, “period is closed!”) unless
self.entry.period.open?; end”?
I am a tad frustrated with AR after seeing all the statements
generated, but the user is probably to blame for a lot of it.
It also seems like the same row gets loaded again every time it’s
used? Perhaps AR could benefit from a per-request cache, or would that
do more harm than good? Say every result set with less than 5 rows
gets cached until the request is finished?
Any input/suggestions appreciated,
Isak