later you may see

in support of blog driven development for Ruby on Rails

One quick tip for db performance on Rails

with 2 comments

Make sure you add indexes to your migrations. Most of the time db performance problems are SQL related. Most of the time the SQL is fairly innocuous. A lot of the time though, in loading the objects the SQL will work best if the candidate keys on the many side of the equation are indexed columns. Create models through generators and either add the indexes to the added migrations or add new migrations to make sure that not only the id primary key indexes are created, but the supporting indexes (like user_id, tagging_id, rateable_asset_id) are also indexed.

Finally, note that cardinality and composition is important in indexes:
Given an index on column A, index on B, index on C
And a query which searches for conditions on A,B,C , then index A is being used most probably alone. If Index A is a low cardinality index (like a flag) then the query is going to scan the whole index which is just as bad as a full table read. The execution plan will say Index read but performance will be awful . B or C might be even faster choices than A, but by having query look at A and an index on A your query is going to go with the slow performing read.

So make sure your indexes are useful, if B gives better spread than A, and your query is asking for conditons on A,B,C then make your index a composite B,A,C order and the SQL will fly.

All of this of course should be transparent to the app side in rails. All of this can be handled via migrations, and will work equally well on all DB choices Rails provides.

Written by Alfonso Adriasola

July 30, 2009 at 10:13 AM

Posted in db, ruby

Tagged with , , ,

2 Responses

Subscribe to comments with RSS.

  1. This isn’t quite true. If you have 3 indexes on 3 columns, MySQL (and other databases) will attempt to choose the best index for the given query. It may not always get it correct, but it certainly will not always choose the first.

    Tom Ward

    August 11, 2009 at 8:35 AM

    • Hmmm you’re missing the point. The three individual indexes will be evaluated for the query conditions. If the query conditions involve columns on all three indexes the resulting index concatenation operation can easily get into a really bad performing execution path due to the cardinality of each index. An index on Gender for example , an Index on a flag where NOT NULL is enforced on the flag.

      Some folks get to that point, look at the planned execution see no full tables scans and then conclude the db is slow.

      FWIW

      Alfonso

      August 11, 2009 at 9:20 AM


Leave a comment