Roderick van Domburg wrote:
Well, you sure have got an awesome proof of concept! Why don't you take
it up with the maintainer of the PostgreSQL adapter or the core team? It
would be great to see more of this.
Thank you! However...
If this was for the PostgreSQL adapter and only the PostgreSQL adapter,
that might be worth doing, but it's more than that. Any database
supporting prepared statements could do this.
Let's turn it into a wrapper around all the calls to select and insert
for all the databases that support it. That would be great, right?
Actually, not really, for several reasons.
1) even if it was rewritten to do proper parsing of the SQL, it would
still cause unnecessary overhead (possibly even more so if it did
proper parsing)
2) there's no control over when the prepared statements are being made.
Here I use a minimum of 3 times, then the statement is prepared. In a
production setting that would mean that almost every statement is
prepared, which isn't optimal. Higher limits would still get just about
every query prepared, which isn't always optimal.
3) if this was solid it would still only be treating the symptoms and
hiding the real problem
What real problem? ActiveRecord is, uhm... well, let's just say it's
not well structured for this kind of thing (I'd love to be proven wrong
on this) and needs to be refactored, and rewritten in large parts, if
this was to be done cleanly. SQL statements are built in several parts,
piece for piece, and no information is saved about what actually goes
into it.
That's why we need to parse the SQL string to find things we should
already know. ActiveRecord made that SQL string, so ActiveRecord should
know what variables, tables and values are in there, and we should be
able to use that to do useful things like prepare/execute before it
hits the adapter.
Adapters are stupid, and they should be. I think ActiveRecord is stupid
because it's throwing all this information away, and it shouldn't be.
Ideally ActiveRecord would use a slightly more abstract format for
queries that then gets turned into SQL in one place... and while I
don't know a lot about ActiveResource, standing on the outside and
looking in, it seems to me like it should be an ActiveRecord with
different storage.
A method like 'delete' shouldn't build a SQL string, it should send a
delete message to the object's storage object, whether it's REST or SQL
or something else (file based storage could have some uses I bet).
Or implementing caching for all "ActiveObjects", which should also be
done above the SQL/REST stuff, there's no way to do that either from
what I can tell.
I bet I'm going to have to regret that last part.
Anyways, the main focus is and should be that ActiveRecord isn't very
well structured for implementing features like prepare/execute, and
until it is, I can't see how it can be done well. And if we can't do it
well, we might as well not do it at all (unless it's for testing or
research, like this was).
If I'm wrong and there is a good way to implement it, it should be made
a top priority for 2.0 or 2.1, because this is more important that
providing even more helpers.
People like to call Ruby on Rails slow, and the defenders like to say
that most of the time is spent in the database anyway, yet here we
could get a huge database increase and yet it's still not done. Someone
posted a couple of weeks ago about how he had been called up by the DBA
and was told to shut down his Rails application because it caused too
much load on the database, and 80% of the time was spent preparing
statements.
I don't think there's any good excuse for this, and it's time to do
something about it, but this here isn't the way to go.
In my humble opinion.
Probably came across as pompous bastard there, which wasn't my
intention. I'd love to help working on a real solution to this problem
but I don't know where to start (and even if I did, I couldn't do it
alone, and if I did it wouldn't be accepted anyways). I'm trying to
show how useful prepared statements can be to hopefully bring some more
attention to this.