<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>PaulBarry.com - Correlated Subqueries</title>
  <subtitle type="html">My thoughts, ideas, questions and concerns on technology, sports, music and life</subtitle>
  <id>tag:paulbarry.com,2007:Paulbarry.com</id>
  <generator uri="http://www.paulbarry.com" version="3.0">PaulBarry.com</generator>
  <link href="http://paulbarry.com/xml/atom/article/4855/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="http://paulbarry.com/articles/2008/01/06/correlated-subqueries" rel="alternate" type="text/html"/>

  <updated>2009-01-05T21:07:06-05:00</updated>
  <entry>
    <author>
      <name>Paul Barry</name>
      <email>mail@paulbarry.com</email>
    </author>
    <id>urn:uuid:f4cc9a01-2727-40f6-b281-0fb770de696b</id>

    <published>2008-01-06T20:58:56-05:00</published>
    <updated>2008-01-06T20:58:56-05:00</updated>
    <title type="html">Correlated Subqueries</title>
    <link href="http://paulbarry.com/articles/2008/01/06/correlated-subqueries" rel="alternate" type="text/html"/>

    <category term="technology" scheme="http://paulbarry.com/articles/category/technology" label="Technology"/>
        <category term="ActiveRecord" scheme="http://paulbarry.com/articles/tag/activerecord"/>
    <category term="MySQL" scheme="http://paulbarry.com/articles/tag/mysql"/>
        <summary type="html">&lt;p&gt;The Rails&apos; ORM ActiveRecord has support for counter caches.  Say you have a blog, like this one, which has articles, and each article has many comments.  If you are going to show a list of articles with the number of comments each article has, without a counter cache, you will end up with N+1 SQL queries.  One query to get the articles, and one &lt;code&gt;select count(*) from comments where article_id = ?&lt;/code&gt; query for each article.  &lt;/p&gt;

&lt;p&gt;To avoid the N+1 select, you can add a column in the articles table that contains the number of comments the article has.  With some ORM frameworks, this becomes somewhat of a pain, because you have to keep that count column updated, but ActiveRecord makes it easy.  If you just create a table called &lt;code&gt;&amp;lt;table_name&amp;gt;_count&lt;/code&gt; on a parent table, it will keep the total of the records that belong to that record in that column.  So then when you call &lt;code&gt;article.comments_count&lt;/code&gt;, there is no SQL query executed.&lt;/p&gt;

&lt;p&gt;This is nice, but what happens if you have a site in production and you want to add a counter cache column?  You&apos;ve got to create the column and then get the count updated.  You can do this in a migration, but you can also do it in SQL using a &lt;a href=&quot;http://dev.mysql.com/doc/refman/4.1/en/correlated-subqueries.html&quot;&gt;correlated subquery&lt;/a&gt;.  Using MySQL, you can do it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;alter table articles add column comments_count int(11) default 0;
update articles set articles.comments_count = 
  (select count(comments.id) from comments where articles.id = comments.article_id);
&lt;/code&gt;&lt;/pre&gt;
</summary>
    <content type="html">&lt;p&gt;The Rails&apos; ORM ActiveRecord has support for counter caches.  Say you have a blog, like this one, which has articles, and each article has many comments.  If you are going to show a list of articles with the number of comments each article has, without a counter cache, you will end up with N+1 SQL queries.  One query to get the articles, and one &lt;code&gt;select count(*) from comments where article_id = ?&lt;/code&gt; query for each article.  &lt;/p&gt;

&lt;p&gt;To avoid the N+1 select, you can add a column in the articles table that contains the number of comments the article has.  With some ORM frameworks, this becomes somewhat of a pain, because you have to keep that count column updated, but ActiveRecord makes it easy.  If you just create a table called &lt;code&gt;&amp;lt;table_name&amp;gt;_count&lt;/code&gt; on a parent table, it will keep the total of the records that belong to that record in that column.  So then when you call &lt;code&gt;article.comments_count&lt;/code&gt;, there is no SQL query executed.&lt;/p&gt;

&lt;p&gt;This is nice, but what happens if you have a site in production and you want to add a counter cache column?  You&apos;ve got to create the column and then get the count updated.  You can do this in a migration, but you can also do it in SQL using a &lt;a href=&quot;http://dev.mysql.com/doc/refman/4.1/en/correlated-subqueries.html&quot;&gt;correlated subquery&lt;/a&gt;.  Using MySQL, you can do it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;alter table articles add column comments_count int(11) default 0;
update articles set articles.comments_count = 
  (select count(comments.id) from comments where articles.id = comments.article_id);
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  </feed>