<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>I.NFECTIO.US: MySQL Query Analyzer Rails Plugin</title>
    <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>"Nothing in life is worth doing if you have no life while doing it"</description>
    <item>
      <title>MySQL Query Analyzer Rails Plugin</title>
      <description>Anyone thats ever grown an application from a couple thousand hits a day to a couple hundred thousand has run into db optimization issues at some point. The best teacher is experience and &lt;a href="http://www.bravenet.com/"&gt;Bravenet&lt;/a&gt; was a great teacher. 
&lt;br /&gt;&lt;br /&gt;
During Bravenets prime years, we had six load-balanced clusters, each with 5 webservers and one MySQL database server. Our userbase was partitioned over these 6 clusters. At peak times, our Queries Per Second on the database servers were over 900 on each. Each page made a minimum of 3-5 database queries (this was before caching became common place) and our traffic load was quite high, so high in fact that a poorly optimized PHP page or a non-indexed query would bring Bravenet down instantly requiring us to fix the script, re-commit and restart all the Apaches to come online. At one point, a nasty bug in our ad-serving code has us down for over 24 hours, it turned out that PHP was loading an array of over 10,000 elements on each request. As soon as we fixed it and committed the changes, Bravenet came back to life.
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Premature Optimization&lt;/h2&gt;
Fine concept for code but practicing it with your database is more akin to Immature Optimization. While it's common place to put indexes on your conditions columns and primary/foreign keys, sometimes (especially in Rails Schema) you just forget. If your writing a small application, you may never see the effects of your error, but as your application grows, it will quickly show itself by slowing down the load time of your pages.&lt;br /&gt;&lt;br /&gt;

&lt;img src="http://i.nfectio.us/files/qa.png" alt="MySQL Query Analyzer" /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;MySQL Query Analyzer&lt;/h2&gt;
With all that said, I wrote a plugin to make it easier to catch those mistakes and stay on top of your database optimizations. This plugin makes use of the &lt;a href="http://www.mysql.org/doc/refman/5.0/en/explain.html"&gt;EXPLAIN&lt;/a&gt; sql statement in MySQL to print out how MySQL formed its execution plan. Basically, for each SELECT query your application runs in the development or testing environments, Rails will also print the query execution plan right after it so you can quickly analyze the queries Rails is making and either add indexes, reorder your joins and remove unneeded or redundant indexes.
&lt;br /&gt;&lt;br /&gt;
To install:
&lt;br /&gt;
script/plugin install http://svn.nfectio.us/plugins/query_analyzer
&lt;br /&gt;&lt;br /&gt;
Read the README for more information. Any feedback or improvements welcome. Good luck and don't be immature.&lt;br /&gt;&lt;br /&gt;</description>
      <pubDate>Wed, 20 Sep 2006 21:54:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:e1a65fce-b44f-423d-baeb-704154b23436</guid>
      <author>Bob Silva</author>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin</link>
      <category>Ruby on Rails</category>
      <category>rails</category>
      <category>mysql</category>
      <category>plugin</category>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Barry</title>
      <description>its okay - i just commented out require 'query_analyzer' in query_analyzer/init.rb</description>
      <pubDate>Sun, 10 Dec 2006 12:29:30 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:af6c7d60-6387-4fec-bbcc-dc8e674bf054</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-233</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Barry</title>
      <description>How to you 'turn it off' once installed? I want to enable &amp; disable when necessary.

Cheers.</description>
      <pubDate>Sun, 10 Dec 2006 12:26:39 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:8bec2a0e-d6f9-44af-becc-490ddb6f0c21</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-232</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Luca Mearelli</title>
      <description>thanks for your plugin (which i found through a comment in the rails way) i find invaluable to optimize the database!
I have added postgresql and oracle support to it (you can find it here: &lt;a href="http://www.spazidigitali.com/2006/12/01/rails-query-analyzer-plugin-now-also-on-oracle-and-postgresql/" rel="nofollow"&gt;http://www.spazidigitali.com/2006/12/01/rails-query-analyzer-plugin-now-also-on-oracle-and-postgresql/&lt;/a&gt;
). it would be nice if you could integrate my additions to your codebase as I don't want to fork it :-) </description>
      <pubDate>Fri, 01 Dec 2006 02:51:57 -0800</pubDate>
      <guid isPermaLink="false">urn:uuid:3ed02528-29bf-43bc-a154-09c9f678ab5f</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-229</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Al Brown</title>
      <description>Woa!  This is great.  Thanks.  

But could make it easier to add to my app?  Cutting and pasting that plugin command was so hard on the wrist.  It took over a minute to get this working.</description>
      <pubDate>Tue, 24 Oct 2006 18:15:44 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:7be76182-3a8a-4f6d-ae73-3b9f9c69819e</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-196</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Matte</title>
      <description>Thanks for this useful tools to optimize our web applications! I add many indexes to my tables, especially for tables using polymorphism.
</description>
      <pubDate>Tue, 24 Oct 2006 05:17:11 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:10640eb7-55c2-4d22-9de6-9de918ce77a3</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-195</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Bob Silva</title>
      <description>Just an update, I've updated the SVN with a newer version to ignore SHOW queries.</description>
      <pubDate>Wed, 04 Oct 2006 21:41:21 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:0bddbf21-0272-4efa-aea1-f34d799aa630</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-174</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Simon Nicholls</title>
      <description>Great idea! Repository revision 12 version (the "darn it" release!) works pretty much as-is with PostgreSQLAdapter too. Just a different adapter name, plus "explain analyze" is usually more helpful on PostgreSQL. Could even be extended to auto-warn of detected no-no queries or fail tests. Thanks Bob</description>
      <pubDate>Wed, 27 Sep 2006 01:20:29 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:f66cbee9-72c7-448a-8aab-ce3900bc3fd3</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-165</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Colin Mitchell</title>
      <description>I had the same problem, and modified line 40 of lib/query_analyzer to look like this:


if sql[0..5].downcase == "select" and @logger and @logger.level = Logger::INFO


Thanks for the great plugin!  It's been really useful after just a couple days of use.</description>
      <pubDate>Tue, 26 Sep 2006 07:31:11 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:3d59546b-517e-4e91-843e-a2fa35e499ed</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-162</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Bob Silva</title>
      <description>I'll modify it so that it doesn't catch SHOW * queries as there is no reason to analyze them. Not sure when I'll get to it though.</description>
      <pubDate>Tue, 26 Sep 2006 01:08:26 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:a659d4fd-7de9-4468-a3a0-a40181aed75f</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-159</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Curtis</title>
      <description>Yeah I agree with JGeiger.  I have the same problem.</description>
      <pubDate>Mon, 25 Sep 2006 12:25:50 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:05989ef6-7d12-4b9e-9480-c448f98c6a64</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-158</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Curtis</title>
      <description>Yeah I agree with JGeiger.  I have the same problem.</description>
      <pubDate>Mon, 25 Sep 2006 12:25:46 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:9c8fe96b-60d7-4360-b113-0062bc9428aa</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-157</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by JGeiger</title>
      <description>If you're using SQL commands to create your test environment:
config.active_record.schema_format = :sql
The plugin doesn't allow the test databases to be recreated, as it tries to EXPLAIN the table creation.
"explain SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"

Would it be possible to add in some flag that only runs the plugin during testing, or at least avoid the rake tasks to prepare the databases?

As a quick fix, i removed the require from the init.rb and moved it into the test_helper.rb and it's working now, with the side effect that it doesn't work in development, which is ok for now.</description>
      <pubDate>Mon, 25 Sep 2006 09:09:57 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:64a7023f-5c91-41d4-9d39-1b31f894590c</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-156</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Bob Silva</title>
      <description>All fixed now and should be accessible to all.</description>
      <pubDate>Thu, 21 Sep 2006 12:22:40 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:fcbba620-52c7-4dbc-a3df-1b720e90bfb9</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-150</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Bob Silva</title>
      <description>Looks like I'm having somoe firewall issues, I'll get it fixed ASAP.</description>
      <pubDate>Thu, 21 Sep 2006 12:07:32 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:70a91214-1023-4f1b-a2ab-93339697f806</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-149</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Anthony Eden</title>
      <description>I'd love to try it but it looks like your Subversion repo isn't responding right now. :-(</description>
      <pubDate>Thu, 21 Sep 2006 08:14:21 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:2e1c1838-218a-4904-8a6a-e4ed499e94d3</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-147</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Ruby Licious</title>
      <description>This is a good idea, i like your work. (Im using your acts_as_threaded heavily btw :)..)

A couple of months ago I thought of an idea that's slighty rellated to your new plugin:

Wouldn't it be possible to even suggest optimization/indexes/keys to add to peoples tables? Or Even have a mode do it automaticly after X hours/days or Y amount of queries to get a good base for analysis.

Should be pretty easy to single out some basic good candidations for new indexes from slow WHEREs, ORDER BYs and LEFT JOIN ONs?

SQL-newbies would love this? :) It could also work as a reminder/support for ppl who know how this works but still have very complex databases.

Just a crazy idea...
</description>
      <pubDate>Thu, 21 Sep 2006 03:38:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:0d4743e2-7e45-46a5-a822-073435e32107</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-146</link>
    </item>
    <item>
      <title>"MySQL Query Analyzer Rails Plugin" by Joe Ruby</title>
      <description>Hmm, not a bad idea. :) I take it that it logs to dev/test.log? Will it also support PostgreSQL (which I think wouldn't be more than trivial)?

That's quite a setup Bravenet had. I've admined sites getting up to 50-100K daily uniques (with probably 10x page views) served by a single server (web, app, db, everything). Aggregate queries were the killer -- once I cached those, the sites (each on their own server) held up pretty well (of course all where'd columns were indexed -- another performance killer if not done).</description>
      <pubDate>Thu, 21 Sep 2006 01:04:28 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:af796016-7558-4e99-94f6-42703f505676</guid>
      <link>http://i.nfectio.us/articles/2006/09/20/mysql-query-analyzer-rails-plugin#comment-145</link>
    </item>
  </channel>
</rss>
