<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MySQL Performance Blog &#187; optimizer</title>
	<atom:link href="http://www.mysqlperformanceblog.com/category/optimizer/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlperformanceblog.com</link>
	<description>Everything about MySQL Performance</description>
	<lastBuildDate>Sat, 21 Nov 2009 03:11:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Quick comparison of MyISAM, Infobright, and MonetDB</title>
		<link>http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 02:56:58 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[myisam]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimizer]]></category>
		<category><![CDATA[Infobright]]></category>
		<category><![CDATA[MonetDB]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1258</guid>
		<description><![CDATA[Recently I was doing a little work for a client who has MyISAM tables with many columns (the same one Peter wrote about recently).  The client's performance is suffering in part because of the number of columns, which is over 200.  The queries are generally pretty simple (sums of columns), but they're ad-hoc [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was doing a little work for a client who has MyISAM tables with many columns (the same one <a href="http://www.mysqlperformanceblog.com/2009/09/28/how-number-of-columns-affects-performance/">Peter wrote about recently</a>).  The client's performance is suffering in part because of the number of columns, which is over 200.  The queries are generally pretty simple (sums of columns), but they're ad-hoc (can access any columns) and it seems tailor-made for a column-oriented database.</p>
<p>I decided it was time to actually give <a href="http://www.infobright.org/">Infobright</a> a try.  They have an open-source community edition, which is crippled but not enough to matter for this test.  The "Knowledge Grid" architecture seems ideal for the types of queries the client runs.  But hey, why not also try <a href="http://monetdb.cwi.nl/">MonetDB</a>, another open-source column-oriented database I've been meaning to take a look at?</p>
<p>What follows is not a realistic benchmark, it's not scientific, it's just some quick and dirty tinkering.  I threw up an Ubuntu 9.04 small server on Amazon.  (I used this version because there's a .deb of MonetDB for it).  I created a table with 200 integer columns and loaded it with random numbers between 0 and 10000.  Initially I wanted to try with 4 million rows, but I had trouble with MonetDB -- there was not enough memory for this.  I didn't do anything fancy with the Amazon server -- I didn't fill up the /mnt disk to claim the bits, for example.  I used default tuning, out of the box, for all three databases.</p>
<p>The first thing I tried doing was loading the data with SQL statements.  I wanted to see how fast MyISAM vs. MonetDB would interpret really large INSERT statements, the kind produced by mysqldump.  But MonetDB choked and told me the number of columns mismatched.  I found reference to this on the mailing list, and skipped that.  I used LOAD DATA INFILE instead (MonetDB's version of that is COPY INTO).  This is the only way to get data into Infobright, anyway.</p>
<h3>The tests</h3>
<p>I loaded 1 million rows into the table.  Here's a graph of the times (smaller is better):</p>
<p><img class="alignnone size-full wp-image-1259" title="Load Time" src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/09/load_time.png" alt="Load Time" width="450" height="320" /></p>
<p>MyISAM took 88 seconds, MonetDB took 200, and Infobright took 486.  Here's the size of the resulting table on disk (smaller is better):</p>
<p><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/09/table_size_bytes.png" alt="Table Size in Bytes" title="Table Size in Bytes" width="450" height="320" class="alignnone size-full wp-image-1270" /></p>
<p>MyISAM is 787MB, MonetDB is 791MB, and Infobright is 317MB.  Next I ran three queries:</p>
<div class="igBar"><span id="lsql-2"><a href="#" onclick="javascript:showPlainTxt('sql-2'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-2">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>c19<span style="color:#006600; font-weight:bold;">&#41;</span>, sum<span style="color:#006600; font-weight:bold;">&#40;</span>c89<span style="color:#006600; font-weight:bold;">&#41;</span>, sum<span style="color:#006600; font-weight:bold;">&#40;</span>c129<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> t;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>c19<span style="color:#006600; font-weight:bold;">&#41;</span>, sum<span style="color:#006600; font-weight:bold;">&#40;</span>c89<span style="color:#006600; font-weight:bold;">&#41;</span>, sum<span style="color:#006600; font-weight:bold;">&#40;</span>c129<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> t <span style="color: #993333; font-weight: bold;">WHERE</span> c11&gt; <span style="color: #cc66cc;color:#800000;">5</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>c19<span style="color:#006600; font-weight:bold;">&#41;</span>, sum<span style="color:#006600; font-weight:bold;">&#40;</span>c89<span style="color:#006600; font-weight:bold;">&#41;</span>, sum<span style="color:#006600; font-weight:bold;">&#40;</span>c129<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> t <span style="color: #993333; font-weight: bold;">WHERE</span> c11 &lt;<span style="color: #cc66cc;color:#800000;">5</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Graphs of query performance time for all three databases are really not very helpful, because MyISAM is so much slower that you can't see the graphs for the others.  So I'll give the numbers and then omit MyISAM from the graphs.  Here are the numbers for everything I measured:</p>
<table borders="1">
<thead>
<tr>
<td></td>
<th>myisam</th>
<th>monetdb</th>
<th>infobright</th>
</tr>
</thead>
<tr>
<th>size (bytes)    </th>
<td>826000000    </td>
<td>829946723</td>
<td>332497242</td>
</tr>
<tr>
<th>load time (seconds)    </th>
<td>88    </td>
<td>200    </td>
<td>486</td>
</tr>
<tr>
<th>query1 time    </th>
<td>3.4    </td>
<td>0.012    </td>
<td>0.0007</td>
</tr>
<tr>
<th>query2 time    </th>
<td>3.4    </td>
<td>0.15    </td>
<td>1.2</td>
</tr>
<tr>
<th>query3 time    </th>
<td>2.5    </td>
<td>0.076    </td>
<td>0.15</td>
</tr>
</table>
<p>And here is a graph of Infobright duking it out with MonetDB on the three queries I tested (shorter bar is better):</p>
<p><img src="http://www.mysqlperformanceblog.com/wp-content/uploads/2009/09/monetdb_infobright_query_time1.png" alt="MonetDB vs Infobright Query Time" title="MonetDB vs Infobright Query Time" width="492" height="320" class="alignnone size-full wp-image-1265" /></p>
<p>I ran each query a few times, discarded the first run, and averaged the next three together.</p>
<h3>Notes on Infobright</h3>
<p>A few miscellaneous notes: don't forget that Infobright is <em>not</em> just a storage engine plugged into MySQL.  It's a complete server with a different optimizer, etc.  This point was hammered home during the LOAD DATA INFILE, when I looked to see what was taking so long (I was tempted to use oprofile and see if there are sleep() statements).  What did I see in 'top' but a program called bhloader.  This bhloader program was the only thing doing anything; mysqld wasn't doing a thing.  LOAD DATA INFILE in Infobright isn't what it seems to be.  Otherwise, Infobright behaved about as I expected it to; it seemed pretty normal to a MySQL guy.</p>
<h3>Notes on MonetDB</h3>
<p>MonetDB was a bit different.  I had to be a bit resourceful to get everything going.  The documentation was for an old version, and was pretty sparse.  I had to go to the mailing lists to find the correct COPY syntax -- it wasn't that listed in the online manual.  And there were funny things like a "merovingian" process (think "angel") that had to be started before the server would start, and I had to destroy the demo database and recreate it before I could start it as shown in the tutorials.</p>
<p>MonetDB has some unexpected properties; it is not a regular RDBMS.  Still, I'm quite impressed by it in some ways.  For example, it seems quite nicely put together, and it's not at all hard to learn.</p>
<p>It doesn't really "speak SQL" -- it speaks relational algebra, and the SQL is just a front-end to it.  You can talk XQuery to it, too.  I'm not sure if you can talk dirty to it, but you can sure talk nerdy to it: you can, should you choose to, give it instructions in MonetDB Assembly Language (MAL), the underlying language.  An abstracted front-end is a great idea; MySQL abstracts the storage backend, but why not do both?  Last I checked, Drizzle is going this direction, hurrah!</p>
<p>EXPLAIN is enlightening and frightening!  You get to see the intermediate code from the compiler.  <a href="http://monetdb.cwi.nl/projects/monetdb/SQL/Documentation/EXPLAIN-Statement.html">The goggles, they do nothing!</a></p>
<p>From what I was able to learn about MonetDB in an hour, I believe it uses memory-mapped files to hold the data in-memory.  If this is true, it explains why I couldn't load 4 million rows into it (this was a 32-bit Amazon machine).</p>
<p>The SQL implementation is impressive.  It's a really solid subset of SQL:2003, much more than I expected.  It even has CTEs, although not recursive ones.  (No, there is no REPLACE, and there is no INSERT/ON DUPLICATE KEY UPDATE.)  I didn't try the XQuery interface.</p>
<p>Although I didn't try it out, there are what looks like pretty useful instrumentation interfaces for profiling, debugging and the like.  The query timer is in milliseconds (why doesn't mysql show query times in microseconds?  I had to resort to Perl + Time::HiRes for timing the Infobright queries).</p>
<p>I think it can be quite useful.  However, I'm not quite sure it's useful for "general-purpose" database use -- there are a number of limitations (concurrency, for one) and it looks like it's still fairly experimental.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/#comments">26 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/&amp;title=Quick comparison of MyISAM, Infobright, and MonetDB" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/&amp;title=Quick comparison of MyISAM, Infobright, and MonetDB" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/&amp;title=Quick comparison of MyISAM, Infobright, and MonetDB" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/&amp;T=Quick comparison of MyISAM, Infobright, and MonetDB" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/&amp;title=Quick comparison of MyISAM, Infobright, and MonetDB" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/09/29/quick-comparison-of-myisam-infobright-and-monetdb/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Guidance for MySQL Optimizer Developers</title>
		<link>http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 03:00:24 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimizer]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1211</guid>
		<description><![CDATA[I spend large portion of my life working on MySQL Performance Optimization and so MySQL Optimizer is quite important to me.   For probably last 10 years I chased first Monty and later Igor with Optimizer complains and suggestions.  Here are some general ideas which I think can help to make optimizer in [...]]]></description>
			<content:encoded><![CDATA[<p>I spend large portion of my life working on MySQL Performance Optimization and so MySQL Optimizer is quite important to me.   For probably last 10 years I chased first Monty and later Igor with Optimizer complains and suggestions.  Here are some general ideas which I think can help to make optimizer in MySQL, MariaDB or Drizzle better.</p>
<p><strong>Make it Plugable</strong>  Every Major optimizer change causes a lot of pain for some of the users.  Even if you improve performance 99 our of 100 queries there are going to be countless users complaining about the change.  Due to this problem Optimizer Team was more conservative than I think they could have been.  The solution is simple - make optimizer pluggable and make it possible to stick to old optimizer behavior with new MySQL Version.  </p>
<p><strong>Make Cost Model Adjustable </strong>  MySQL Optimizer looks at query plan in terms of disk IOs/Seeks in same way for all data sets. In practice some people have their database 100% in RAM (even for Disk tables such MyISAM or Innodb)  others keep database on SSD which has completely different ratio between CPU and IO cost. </p>
<p><strong>Focus on Execution Methods</strong>  Performance problems can be due to optimizer picking the wrong plan, such as doing full table scan when Index access is better or because MySQL simply does not have execution method to resolve query in optimal way - loose index scan, hash join, sort merge join are all the examples of such.  For me it is most important to ensure MySQL has proper ways to execute the query. It may not always pick them right but at least it allows to get query going right manually.</p>
<p><strong>Zero Administration Tunables and Hints</strong>  Zero Administration is great. I would love to see Optimizer which always choses the fastest plan for the query (not the plan with lowest "cost" but the one which actually gives best performance).  I also recognize there are always going to be cases when Optimizer will not pick the right plan.  So I would like to see tuning knobs (which relates to cost model and various optimizations) as well as simply hints.  Any way MySQL could possibly execute query should be possible to force with hints.  In  MySQL 4.0 this was the case, in recent versions number of optimizations have been added which can't be easily forced with hints. </p>
<p>Another benefit of having ways to force any optimizer behavior with hints (rather than by changing the code) is the data Optimizer Team can get back from customers and community - it because very easy for users to show there is the plan which works better and so let the team know which cases are not handled best by the optimizer logic.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/#comments">4 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/&amp;title=Guidance for MySQL Optimizer Developers" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/&amp;title=Guidance for MySQL Optimizer Developers" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/&amp;title=Guidance for MySQL Optimizer Developers" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/&amp;T=Guidance for MySQL Optimizer Developers" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/&amp;title=Guidance for MySQL Optimizer Developers" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/09/20/guidance-for-mysql-optimizer-developers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Multi Column indexes vs Index Merge</title>
		<link>http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 16:10:48 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[optimizer]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1206</guid>
		<description><![CDATA[The mistake I commonly see among MySQL users is how indexes are created.  Quite commonly people just index individual columns as they are referenced in where clause thinking this is the optimal indexing strategy.  For example if I would have something like  AGE=18 AND STATE='CA' they would create 2 separate indexes on [...]]]></description>
			<content:encoded><![CDATA[<p>The mistake I commonly see among MySQL users is how indexes are created.  Quite commonly people just index individual columns as they are referenced in where clause thinking this is the optimal indexing strategy.  For example if I would have something like  <strong>AGE=18 AND STATE='CA'</strong> they would create 2 separate indexes on AGE and STATE columns. </p>
<p>The better strategy is often to have combined multi-column index on (AGE,STATE).  Lets see why it is the case.</p>
<p>MySQL indexes are (with few exceptions) BTREE indexes - this index type is very good to be able to quickly lookup the data on any its prefix and traversing ranges between values in sorted order.   For example when you query AGE=18 with single column BTREE index  MySQL will dive into the index to find first matching row and when will continue scanning index in order until it runs into the value of AGE more than 18 when it stops doing so assuming there are no more matching.  The RANGES such as AGE BETWEEN 18 AND 20 work similar way - MySQL just stops at different value.</p>
<p>The enumerated ranges such as AGE IN (18,20,30)  are more complicated as this is in fact several separate index lookups.</p>
<p>So we spoke about how MySQL uses the index but not exactly what it gets from the index - typically (unless it is covering index) MySQL gets a "row pointer"  which can be primary key value (for Innodb tables)  physical file offset (for MyISAM tables) or something else.    It is important internally storage engine can use that value to lookup the full row data corresponding to the given index entry.</p>
<p>So what choices does MySQL have if you have just 2 separate indexes ?  I will either use just one of them to look up the data (and check remaining portion on WHERE clause after data is read) or it can lookup the row pointers from all indexes, intersect them and when lookup the data. </p>
<p>Which method works better depends on selectivity and correlation.  If  where clause from first column selects 5% of the rows and applying where clause on second column brings it down to 1%   using intersection makes sense.  If second where clause just brings it down to 4.5%  it is most likely better to use single index only and simply filter out rows we do not need after lookup.</p>
<p>Lets look at some examples now:</p>
<div class="igBar"><span id="lsql-15"><a href="#" onclick="javascript:showPlainTxt('sql-15'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-15">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`idxtest`</span> <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`i1`</span> int<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`i2`</span> int<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`val`</span> varchar<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">40</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`i1`</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">`i1`</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`i2`</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">`i2`</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`combined`</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">`i1`</span>,<span style="color: #ff0000;">`i2`</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span> ENGINE=MyISAM <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET=latin1 </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I made columns i1 and  i2 independent in this case each selecting about 1% rows from this table which contains about 10M rows.</p>
<div class="igBar"><span id="lsql-16"><a href="#" onclick="javascript:showPlainTxt('sql-16'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-16">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest&nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+----------------+----------+---------+-------------+------+-------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type | possible_keys&nbsp; | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; &nbsp; &nbsp; | key_len | ref&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| rows | Extra |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+----------------+----------+---------+-------------+------+-------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | ref&nbsp; | i1,i2,combined | combined | <span style="color: #cc66cc;color:#800000;">8</span>&nbsp; &nbsp; &nbsp; &nbsp;| const,const |&nbsp; <span style="color: #cc66cc;color:#800000;">665</span> |&nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+----------------+----------+---------+-------------+------+-------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As you can see MySQL picks to use combined index and indeed the query completes in <strong>less than 10ms</strong> </p>
<p>Now what if we pretend we only have single column indexes (by hinting optimizer to ignore combined index)</p>
<div class="igBar"><span id="lsql-17"><a href="#" onclick="javascript:showPlainTxt('sql-17'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-17">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> <span style="color:#006600; font-weight:bold;">&#40;</span>combined<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+---------------+-------+---------+------+------+-------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type&nbsp; &nbsp; &nbsp; &nbsp; | possible_keys | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; &nbsp;| key_len | ref&nbsp; | rows | Extra&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+---------------+-------+---------+------+------+-------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | index_merge | i1,i2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| i1,i2 | <span style="color: #cc66cc;color:#800000;">4</span>,<span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">NULL</span> | <span style="color: #cc66cc;color:#800000;">1032</span> | <span style="color: #993333; font-weight: bold;">USING</span> intersect<span style="color:#006600; font-weight:bold;">&#40;</span>i1,i2<span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+---------------+-------+---------+------+------+-------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As you can see in this case MySQL does the Intersection for the index values (the process a mentioned above) and  the query now runs in about <strong>70 ms</strong>  which is quite a difference.</p>
<p>Now lets see if using just single index and post filtering is any better:</p>
<div class="igBar"><span id="lsql-18"><a href="#" onclick="javascript:showPlainTxt('sql-18'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-18">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> <span style="color:#006600; font-weight:bold;">&#40;</span>combined,i2<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type | possible_keys | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; | key_len | ref&nbsp; &nbsp;| rows&nbsp; &nbsp;| Extra&nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | ref&nbsp; | i1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | i1&nbsp; &nbsp;| <span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp; &nbsp;| const | <span style="color: #cc66cc;color:#800000;">106222</span> | <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Now this query scans a lot of rows and completed in about <strong>290ms</strong><br />
So we can see index merge indeed improves performance compared to single index only but it is by far better to use multi column indexes.</p>
<p>But the problems with Index Merge do not stop there.  It is currently rather restricted in which conditions it would do the index merge:</p>
<div class="igBar"><span id="lsql-19"><a href="#" onclick="javascript:showPlainTxt('sql-19'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-19">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> <span style="color:#006600; font-weight:bold;">&#40;</span>combined<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2 <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">49</span>,<span style="color: #cc66cc;color:#800000;">50</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type | possible_keys | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; | key_len | ref&nbsp; &nbsp;| rows&nbsp; &nbsp;| Extra&nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | ref&nbsp; | i1,i2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| i1&nbsp; &nbsp;| <span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp; &nbsp;| const | <span style="color: #cc66cc;color:#800000;">106222</span> | <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As soon as any of the columns has enumeration instead of equality index merge is not selected any more. Even though in this case it should be good idea as i2 in (49,50) is still rather selective. </p>
<p>Now lets do another test. I've changed the table to make columns i1 and i2 highly correlated. In fact they are now the same:</p>
<div class="igBar"><span id="lsql-20"><a href="#" onclick="javascript:showPlainTxt('sql-20'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-20">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">UPDATE</span> idxtest <span style="color: #993333; font-weight: bold;">SET</span> i2=i1;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Query OK, <span style="color: #cc66cc;color:#800000;">10900996</span> rows affected <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">6</span> min <span style="color: #cc66cc;color:#800000;">47</span>.<span style="color: #cc66cc;color:#800000;">87</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Rows matched: <span style="color: #cc66cc;color:#800000;">11010048</span>&nbsp; Changed: <span style="color: #cc66cc;color:#800000;">10900996</span>&nbsp; Warnings: <span style="color: #cc66cc;color:#800000;">0</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Lets see what happens in this case </p>
<div class="igBar"><span id="lsql-21"><a href="#" onclick="javascript:showPlainTxt('sql-21'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-21">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+------+-------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type&nbsp; &nbsp; &nbsp; &nbsp; | possible_keys&nbsp; | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; &nbsp;| key_len | ref&nbsp; | rows | Extra&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+------+-------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | index_merge | i1,i2,combined | i2,i1 | <span style="color: #cc66cc;color:#800000;">4</span>,<span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">NULL</span> |&nbsp; <span style="color: #cc66cc;color:#800000;">959</span> | <span style="color: #993333; font-weight: bold;">USING</span> intersect<span style="color:#006600; font-weight:bold;">&#40;</span>i2,i1<span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+------+-------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Hm... Optimizer decides to use index merge in this case which is probably the worse decision it could do.  Indeed the query takes <strong>360ms</strong>   Note also the estimated values of  "rows" is very wrong here.     </p>
<p>This happens because Optimizer assumes columns i1 and i2 are independent estimating selectivity for the intersection.  This is as good as it can to because there is no correlation statistics available.</p>
<div class="igBar"><span id="lsql-22"><a href="#" onclick="javascript:showPlainTxt('sql-22'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-22">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt;&nbsp; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">INDEX</span><span style="color:#006600; font-weight:bold;">&#40;</span>i2<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type | possible_keys | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; | key_len | ref&nbsp; &nbsp;| rows&nbsp; &nbsp;| Extra&nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | ref&nbsp; | i1,combined&nbsp; &nbsp;| i1&nbsp; &nbsp;| <span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp; &nbsp;| const | <span style="color: #cc66cc;color:#800000;">106222</span> | <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+-------+--------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Now if we do not allow MySQL optimizer to use second index and hence index merge, what does it turn to ? It is not combined index but single index on another column.  This is because  MySQL is able to estimate number of rows it will find using both indexes and as  they are about the same it picks smaller index.  The query <strong>takes 290ms</strong>  which is exactly what we've seen before. </p>
<p>What if we leave MySQL no choice but only to use combined index:</p>
<div class="igBar"><span id="lsql-23"><a href="#" onclick="javascript:showPlainTxt('sql-23'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-23">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">INDEX</span><span style="color:#006600; font-weight:bold;">&#40;</span>i1,i2<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">AND</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+----------+---------+-------------+--------+-------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type | possible_keys | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; &nbsp; &nbsp; | key_len | ref&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| rows&nbsp; &nbsp;| Extra |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+----------+---------+-------------+--------+-------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | ref&nbsp; | combined&nbsp; &nbsp; &nbsp; | combined | <span style="color: #cc66cc;color:#800000;">8</span>&nbsp; &nbsp; &nbsp; &nbsp;| const,const | <span style="color: #cc66cc;color:#800000;">121137</span> |&nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+----------+---------+-------------+--------+-------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>We can see here MySQL estimates 20% more rows to traverse, which is wrong of course - it can't be more than if only index prefix is used.  MySQL does not know it as it looks at stats from different indexes independently not trying to reconcile them some way.</p>
<p>Because index is longer query execution takes a bit longer - <strong>300ms</strong> </p>
<p>So in this case we see index merge is chosen even though it turns out to be the worst plan.  Though technically it is right plan considering the statistics MySQL had available.</p>
<p>It is very easy to disable index merge if you do not want it to run, however I do not know of the hint in MySQL which would allow forcing using index merge when MySQL does not think it should be used.  I hope hint would be added at some point. </p>
<p>Finally let me mention the case when Index merge works much better than multiple column indexes.  This is in case you're using <strong>OR</strong>   between the columns.  In this case the combined index is useless and MySQL has an option of doing full table scan or doing the Union (instead of intersection) on values it gets from the single table.</p>
<p>I have reverted table to have i1 and i2 as independent columns in this case to look at more typical case:</p>
<div class="igBar"><span id="lsql-24"><a href="#" onclick="javascript:showPlainTxt('sql-24'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-24">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">OR</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+--------+---------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type&nbsp; &nbsp; &nbsp; &nbsp; | possible_keys&nbsp; | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; &nbsp;| key_len | ref&nbsp; | rows&nbsp; &nbsp;| Extra&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+--------+---------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | index_merge | i1,i2,combined | i1,i2 | <span style="color: #cc66cc;color:#800000;">4</span>,<span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">NULL</span> | <span style="color: #cc66cc;color:#800000;">203803</span> | <span style="color: #993333; font-weight: bold;">USING</span> union<span style="color:#006600; font-weight:bold;">&#40;</span>i1,i2<span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+--------+---------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>This query takes <strong>660ms</strong> to execute. now if we change it:</p>
<p>If we disable index on the second column we get a full table scan:</p>
<div class="igBar"><span id="lsql-25"><a href="#" onclick="javascript:showPlainTxt('sql-25'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-25">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">INDEX</span><span style="color:#006600; font-weight:bold;">&#40;</span>i2<span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">OR</span> i2=<span style="color: #cc66cc;color:#800000;">50</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+------+----------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type | possible_keys | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; | key_len | ref&nbsp; | rows&nbsp; &nbsp; &nbsp;| Extra&nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+------+----------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | <span style="color: #993333; font-weight: bold;">ALL</span>&nbsp; | i1,combined&nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">NULL</span> | <span style="color: #993333; font-weight: bold;">NULL</span>&nbsp; &nbsp; | <span style="color: #993333; font-weight: bold;">NULL</span> | <span style="color: #cc66cc;color:#800000;">11010048</span> | <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+------+---------------+------+---------+------+----------+-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Note MySQL puts i1 and combined into "possible_key" while it has no way to use them for this query.</p>
<p>The query takes <strong>3370ms</strong> if this plan is used.</p>
<p>Note the query takes about 5  times longer even though in case of full table scan about 50 times more rows are scanned. This reflects very large performance difference between full table scan and access through the index, which seems to be about 10x (in terms of cost access per row) even though it is in memory workload.</p>
<p>For UNION case the optimizer is more advanced and it is able to deal with ranges:</p>
<div class="igBar"><span id="lsql-26"><a href="#" onclick="javascript:showPlainTxt('sql-26'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-26">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql <span style="color:#006600; font-weight:bold;">&#91;</span>localhost<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>msandbox<span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>test<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> avg<span style="color:#006600; font-weight:bold;">&#40;</span>length<span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> idxtest&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">WHERE</span> i1=<span style="color: #cc66cc;color:#800000;">50</span> <span style="color: #993333; font-weight: bold;">OR</span> i2 <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">49</span>,<span style="color: #cc66cc;color:#800000;">50</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+--------+--------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| id | select_type | <span style="color: #993333; font-weight: bold;">TABLE</span>&nbsp; &nbsp;| type&nbsp; &nbsp; &nbsp; &nbsp; | possible_keys&nbsp; | <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; &nbsp;| key_len | ref&nbsp; | rows&nbsp; &nbsp;| Extra&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+--------+--------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">1</span> | SIMPLE&nbsp; &nbsp; &nbsp; | idxtest | index_merge | i1,i2,combined | i1,i2 | <span style="color: #cc66cc;color:#800000;">4</span>,<span style="color: #cc66cc;color:#800000;">4</span>&nbsp; &nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">NULL</span> | <span style="color: #cc66cc;color:#800000;">299364</span> | <span style="color: #993333; font-weight: bold;">USING</span> sort_union<span style="color:#006600; font-weight:bold;">&#40;</span>i1,i2<span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----+-------------+---------+-------------+----------------+-------+---------+------+--------+--------------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As a summary:   Use multi column indexes is typically best idea if you use AND between such columns in where clause.  Index merge does helps performance but it is far from performance of combined index in this case. In case you're using OR between columns  - single column indexes are required for index merge to work and combined indexes can't be used for such queries.</p>
<p>P.S  The tests were done in <strong>MySQL 5.4.2</strong>  </p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/#comments">22 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/&amp;title=Multi Column indexes vs Index Merge" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/&amp;title=Multi Column indexes vs Index Merge" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/&amp;title=Multi Column indexes vs Index Merge" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/&amp;T=Multi Column indexes vs Index Merge" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/&amp;title=Multi Column indexes vs Index Merge" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/09/19/multi-column-indexes-vs-index-merge/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>A micro-benchmark of stored routines in MySQL</title>
		<link>http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 01:27:43 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[optimizer]]></category>
		<category><![CDATA[stored functions]]></category>
		<category><![CDATA[stored procedures]]></category>
		<category><![CDATA[stored routines]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=1018</guid>
		<description><![CDATA[Ever wondered how fast stored routines are in MySQL?  I just ran a quick micro-benchmark to compare the speed of a stored function against a "roughly equivalent" subquery.  The idea -- and there may be shortcomings that are poisoning the results here, your comments welcome -- is to see how fast the SQL [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wondered how fast stored routines are in MySQL?  I just ran a quick micro-benchmark to compare the speed of a stored function against a "roughly equivalent" subquery.  The idea -- and there may be shortcomings that are poisoning the results here, your comments welcome -- is to see how fast the SQL procedure code is at doing basically the same thing the subquery code does natively (so to speak).</p>
<p>Before we go further, I want to make sure you know that the queries I'm writing here are deliberately mis-optimized to force a bad execution plan.  You should never use IN() subqueries the way I do, at least not in MySQL 5.1 and earlier.</p>
<p>I loaded the World sample database and cooked up this query:</p>
<div class="igBar"><span id="lsql-31"><a href="#" onclick="javascript:showPlainTxt('sql-31'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-31">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> sql_no_cache sum<span style="color:#006600; font-weight:bold;">&#40;</span>ci.Population<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> City <span style="color: #993333; font-weight: bold;">AS</span> ci</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> CountryCode <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">DISTINCT</span> co.Code <span style="color: #993333; font-weight: bold;">FROM</span> Country <span style="color: #993333; font-weight: bold;">AS</span> co</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> CountryLanguage <span style="color: #993333; font-weight: bold;">AS</span> cl <span style="color: #993333; font-weight: bold;">ON</span> cl.CountryCode = co.Code</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> lower<span style="color:#006600; font-weight:bold;">&#40;</span>cl.<span style="color: #993333; font-weight: bold;">LANGUAGE</span><span style="color:#006600; font-weight:bold;">&#41;</span> = <span style="color: #ff0000;">'English'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">--------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| sum<span style="color:#006600; font-weight:bold;">&#40;</span>ci.Population<span style="color:#006600; font-weight:bold;">&#41;</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">--------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #cc66cc;color:#800000;">237134840</span> | </div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">--------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">23</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>This pretty consistently runs in just about 1/4th of a second.  If you look at the abridged explain plan below, you'll see the query is doing a table scan against the first query, and then executing the subquery for each row:</p>
<div class="igBar"><span id="lsql-32"><a href="#" onclick="javascript:showPlainTxt('sql-32'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-32">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> ....\G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: ci</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: <span style="color: #993333; font-weight: bold;">ALL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">4079</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">2</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">2</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: DEPENDENT SUBQUERY</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">3</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">2</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: DEPENDENT SUBQUERY </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Now I took the subquery and basically rewrote it as a stored function.</p>
<div class="igBar"><span id="lsql-33"><a href="#" onclick="javascript:showPlainTxt('sql-33'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-33">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; delimiter //</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> speaks_english<span style="color:#006600; font-weight:bold;">&#40;</span>c char<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> returns integer deterministic</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &gt; begin</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &gt; declare res int;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &gt; <span style="color: #993333; font-weight: bold;">SELECT</span> count<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #993333; font-weight: bold;">DISTINCT</span> co.Code<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">INTO</span> res <span style="color: #993333; font-weight: bold;">FROM</span> Country <span style="color: #993333; font-weight: bold;">AS</span> co <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> CountryLanguage <span style="color: #993333; font-weight: bold;">AS</span> cl <span style="color: #993333; font-weight: bold;">ON</span> cl.CountryCode = co.Code <span style="color: #993333; font-weight: bold;">WHERE</span> lower<span style="color:#006600; font-weight:bold;">&#40;</span>cl.<span style="color: #993333; font-weight: bold;">LANGUAGE</span><span style="color:#006600; font-weight:bold;">&#41;</span> = <span style="color: #ff0000;">'English'</span> <span style="color: #993333; font-weight: bold;">AND</span> co.Code = c;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &gt; <span style="color: #993333; font-weight: bold;">RETURN</span> res;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &gt; end//</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; delimiter ; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Now the query can be rewritten as this:</p>
<div class="igBar"><span id="lsql-34"><a href="#" onclick="javascript:showPlainTxt('sql-34'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-34">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> sql_no_cache sum<span style="color:#006600; font-weight:bold;">&#40;</span>ci.Population<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> City <span style="color: #993333; font-weight: bold;">AS</span> ci <span style="color: #993333; font-weight: bold;">WHERE</span> speaks_english<span style="color:#006600; font-weight:bold;">&#40;</span>CountryCode<span style="color:#006600; font-weight:bold;">&#41;</span>&gt; <span style="color: #cc66cc;color:#800000;">0</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">--------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| sum<span style="color:#006600; font-weight:bold;">&#40;</span>ci.Population<span style="color:#006600; font-weight:bold;">&#41;</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">--------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #cc66cc;color:#800000;">237134840</span> | </div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">--------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">1</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>If we explain it, we get output similar to the first table shown above, but the further two rows are not shown.  The query can't be optimized to use indexes, and the stored function is opaque to the optimizer.  This is why I purposefully wrote the subquery badly in the first query!  (If you think of a better way to compare apples and uhm, apples... please comment).</p>
<p>The poorly-optimized-subquery portion of the query essentially happens inside that function now.</p>
<p>And it's four times slower, consistently, and that's all I wanted to show here.  Thanks for reading.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/#comments">7 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/&amp;title=A micro-benchmark of stored routines in MySQL" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/&amp;title=A micro-benchmark of stored routines in MySQL" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/&amp;title=A micro-benchmark of stored routines in MySQL" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/&amp;T=A micro-benchmark of stored routines in MySQL" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/&amp;title=A micro-benchmark of stored routines in MySQL" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/08/16/a-micro-benchmark-of-stored-routines-in-mysql/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>What does Using filesort mean in MySQL?</title>
		<link>http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/#comments</comments>
		<pubDate>Thu, 05 Mar 2009 20:36:03 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[optimizer]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=635</guid>
		<description><![CDATA[If you were interviewing to work at Percona, and I asked you "what does Using filesort mean in EXPLAIN," what would you say?
I have asked this question in a bunch of interviews so far, with smart people, and not one person has gotten it right.  So I consider it to be a bad interview [...]]]></description>
			<content:encoded><![CDATA[<p>If you were interviewing to work at Percona, and I asked you "what does <em>Using filesort</em> mean in EXPLAIN," what would you say?</p>
<p>I have asked this question in a bunch of interviews so far, with smart people, and not one person has gotten it right.  So I consider it to be a bad interview question, and I'm going to put the answer here.  If anyone gets it wrong from now on, I know they don't read this blog!</p>
<p>The usual answer is something like "rows are being placed into a temporary table which is too big to fit in memory, so it gets sorted on disk."  Unfortunately, this is not the same thing.  First of all, this is <em>Using temporary</em>.  Secondly, temporary tables may go to disk if they are too big, but EXPLAIN doesn't show that.  (If I interview you, I might ask you what "too big" means, or I might ask you the <em>other</em> reason temporary tables go to disk!)</p>
<p>The truth is, filesort is badly named.  Anytime a sort can't be performed from an index, it's a filesort.  It has nothing to do with files.  Filesort should be called "sort." It is <a href="http://en.wikipedia.org/wiki/Quicksort">quicksort</a> at heart.</p>
<p>If the sort is bigger than the sort buffer, it is performed a bit at a time, and then the chunks are merge-sorted to produce the final sorted output.  There is a lot more to it than this.  I refer you to <a href="http://s.petrunia.net/blog/?p=24">Sergey Petrunia's article on How MySQL executes ORDER BY.</a>  You can also read about it in our book, but if you read Sergey's article you won't need to.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/#comments">20 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/&amp;title=What does Using filesort mean in MySQL?" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/&amp;title=What does Using filesort mean in MySQL?" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/&amp;title=What does Using filesort mean in MySQL?" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/&amp;T=What does Using filesort mean in MySQL?" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/&amp;title=What does Using filesort mean in MySQL?" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Optimizing repeated subexpressions in MySQL</title>
		<link>http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/</link>
		<comments>http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 22:28:35 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[optimizer]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=596</guid>
		<description><![CDATA[How smart is the MySQL optimizer?  If it sees an expression repeated many times, does it realize they're all the same and not calculate the result for each of them?
I had a specific case where I needed to find out for sure, so I made a little benchmark.  The query looks something like [...]]]></description>
			<content:encoded><![CDATA[<p>How smart is the MySQL optimizer?  If it sees an expression repeated many times, does it realize they're all the same and not calculate the result for each of them?</p>
<p>I had a specific case where I needed to find out for sure, so I made a little benchmark.  The query looks something like this:</p>
<div class="igBar"><span id="lsql-37"><a href="#" onclick="javascript:showPlainTxt('sql-37'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-37">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> sql_no_cache</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">4</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">5</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">6</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">7</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">8</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">11</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">12</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">13</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">14</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">15</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">16</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">17</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">18</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">FROM</span> sakila.rental; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I wrote a bash script to execute the query 500 times and redirect the results to /dev/null.  Results: 31s wall-clock time.</p>
<p>The following is an alternative query that returns the same result:</p>
<div class="igBar"><span id="lsql-38"><a href="#" onclick="javascript:showPlainTxt('sql-38'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-38">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> sql_no_cache</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum := <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>rental_id<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> sakila.rental<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color: #cc66cc;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">4</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">5</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">6</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">7</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">8</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">11</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">12</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">13</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">14</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">15</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">16</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">17</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp;pow<span style="color:#006600; font-weight:bold;">&#40;</span>@sum, <span style="color: #cc66cc;color:#800000;">18</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>This query runs 500 iterations in 12s.  So it looks like the optimizer was computing the SUM() 18 times in the first query.  (A response on the internals mailing list agreed with this finding.  Thanks Konstantin.)</p>
<p>Along the same lines, I benchmarked POW() and found that squaring a number is more than twice as fast to do with ordinary multiplication as with POW().  Does this matter?  Sometimes... we had a client who was doing vector math in a many-dimensional space, and the POW() seemed to be taking a pretty significant amount of time; changing to ordinary multiplication made the query faster.  (It was not the ultimate suggestion though.)</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/#comments">11 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/&amp;title=Optimizing repeated subexpressions in MySQL" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/&amp;title=Optimizing repeated subexpressions in MySQL" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/&amp;title=Optimizing repeated subexpressions in MySQL" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/&amp;T=Optimizing repeated subexpressions in MySQL" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/&amp;title=Optimizing repeated subexpressions in MySQL" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2009/01/23/optimizing-repeated-subexpressions-in-mysql/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>High-Performance Click Analysis with MySQL</title>
		<link>http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 03:48:17 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[ideas]]></category>
		<category><![CDATA[optimizer]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[xtradb]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=562</guid>
		<description><![CDATA[We have a lot of customers who do click analysis, site analytics, search engine marketing, online advertising, user behavior analysis, and many similar types of work.  The first thing these have in common is that they're generally some kind of loggable event.
The next characteristic of a lot of these systems (real or planned) is the [...]]]></description>
			<content:encoded><![CDATA[<p>We have a lot of customers who do click analysis, site analytics, search engine marketing, online advertising, user behavior analysis, and many similar types of work.  The first thing these have in common is that they're generally some kind of loggable event.</p>
<p>The next characteristic of a lot of these systems (real or planned) is the desire for "real-time" analysis.  Our customers often want their systems to provide the freshest data to their own clients, with no delays.</p>
<p>Finally, the analysis is usually multi-dimensional.  The typical user wants to be able to generate summaries and reports in many different ways on demand, often to support the functionality of the application as well as to provide reports to their clients.  Clicks by day, by customer, top ads by clicks, top ads by click-through ratio, and so on for dozens of different types of slicing and dicing.</p>
<p>And as a result, one of the most common questions we hear is how to build high-performance systems to do this work.  Let's see some ways you can build the functionality you need and get the performance you need.  Because I've built two such systems to manage online ads through Google Adwords, Yahoo, MSN and others, it's easy and familiar for me to use the example of search engine marketing.  I'll do that throughout this article.</p>
<p><strong>Requirements</strong></p>
<p>The words "need" and "want" are different.  Do you really need atomic-level data?  Do you really need real-time reporting?  If you do, the problem is much more expensive to solve.</p>
<p>Start with the granularity of your data.  What data do you need to make your business run?  If you can't get access to the time of day of every click on every ad, will it hamper your ability to measure the ad's value?  Is it enough to know how many times the ad was clicked each day?  If so, you can roll all those events up into a per-day table.</p>
<p>Next, let's look at "real-time."  None of the big three (Google, Yahoo, MSN) provides real-time reporting last time I was involved with them (and I suspect this is still true).  It's too expensive.  Consider your user expectations.  For most applications I've been involved with, having day-old data is adequate, and users don't expect realtime.  The trick here is that when you start out, realtime is possible because your data is small.  "Hey, we do realtime reporting.  Google doesn't even do that!  We're better!" Then you get popular <img src='http://www.mysqlperformanceblog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   And if you've promoted your better-ness in the meantime, you might have to do some awkward backpedaling with customers, who now expect realtime data.  The database giveth, and the database taketh away.</p>
<p>Finally, you should think a lot about how you need to query the data.  It is a hard question to answer, and sometimes I've seen it evolve over time, especially as the growing data size forces it to.  This goes back to what data you really need to make your business run.  Anything else is gravy.  If there are nice-to-haves, consider not building them in.  <a href="http://blip.tv/file/1356502">Listen to some talks by 37Signals</a> if you need inspiration to toss things out.  Define the types of queries you absolutely have to have, if possible, and note the ways and types of aggregation (by-ad by-day, for example).</p>
<p>Sometimes I ask a customer "what kinds of queries do you have to run?" and they say "we can't decide, so we want to just store everything." If you can't decide yet, then don't store everything in the database.  Instead, store the source data in some fashion that you can reload later, such as flat files, and build support in the database for one or two capabilities you absolutely need now; then add the rest later, reloading the data if needed.</p>
<p><strong>Aggregate</strong></p>
<p>Aggregation is absolutely key for most people.  There are special cases, and there are ways to do general-purpose work without aggregating (see the section below on technologies), but if you're doing this with vanilla MySQL, you will need to aggregate your data.</p>
<p>What you want to do is aggregate in ways that optimize the most expensive things you'll do.  And then, you might super-aggregate too.  For example, if you aggregate by day and then you do a lot of queries over 365-day ranges for year-over-year analysis, aggregate again by month.  Then write your queries to use the most aggregated data possible to save work.</p>
<p>Avoid operations that update huge chunks of aggregated data at once.  Among other things, you'll make replication lag badly.  More about this later.</p>
<p>Another way to say "aggregate" is to say "pre-compute."  If you have time-critical queries for your app to do its work, can you do the work ahead of time so it's ready to get when needed?  This might or might not be aggregation.</p>
<p><strong>Denormalize</strong></p>
<p>Pre-computing and careful denormalization need to go together.  Figure out what other types of data you'll need in those aggregate tables, and include columns to support these queries.  But beware of denormalizing with character data; try to make your rows fixed-length.</p>
<p>One reason denormalization is important is that nested-loop joins on large data sets are very expensive.  If MySQL supported sort-merge or hash joins, you'd have other possibilities, but it doesn't, so you want to build your aggregate tables to avoid joins.</p>
<p><strong>Watch Data Types</strong></p>
<p>Does your ad ID look like "8a4dabde-1c82-102c-ab13-0019b984eacd" and is it stored in a VARCHAR(36)?  When tables get big, every byte matters a lot.  Use the smallest data types you can, the simplest character sets you can, and watch out for NULLable columns.  Use smallint unsigned or tinyint unsigned if you can.  You can save very large amounts of space.  Choose primary keys very carefully, especially with InnoDB tables -- don't use GUIDs.  Which brings me to my next point:</p>
<p><strong>Use InnoDB</strong></p>
<p>Assuming that you will use the stock MySQL server, InnoDB is usually your best bet.  (Actually, <a href="https://launchpad.net/percona-xtradb">XtraDB</a> might be very interesting for you, but I digress).  Due to the cost of repairing huge MyISAM tables and taking downtime, I would not use MyISAM for anything but read-only tables when things get big.  And even if it's read-only, there's still another reason to use InnoDB/XtraDB tables...</p>
<p><strong>Optimize For I/O</strong></p>
<p>It is pretty much inevitable: if you do this kind of data processing in MySQL, you're going to end up heavily I/O bound.  Listen to any of the talks at past MySQL conferences from people who have built systems like yours, and there's a fair chance they will talk about how hard they have to work on I/O capacity.</p>
<p>What does this have to do with InnoDB?  Data clustering. InnoDB's primary keys define the physical order rows are stored in.  That lets you choose which rows are stored close to each other, which is very beneficial in many cases.  Especially on huge tables, it lets you scan portions of a table instead of the whole table if you a) choose your aggregation to match the order of your common queries and b) choose your primary key correctly.</p>
<p>Let's go back to the ad-by-day table.  If you query date ranges most of the time, you should define the primary key as (day, ad).  Don't use an auto-increment primary key, and don't put ad first.  If you put ad first, then you're going to scan the whole table to query for information about yesterday.  If you put day first, then yesterday will all be stored physically together (within the page -- the pages themselves may be widely separated, but that's another matter).</p>
<p><strong>Don't Store Non-Aggregated Data</strong></p>
<p>I've been talking a lot about aggregated data.  What do you do with the non-aggregated data?  My answer is usually simple: just don't store it in the database.  Instead, pre-aggregate.  Suppose your data is coming from some Apache log or similar source.  Write a script to rip through the file and parse it 10k lines at a time, aggregating as it goes.  When each chunk is done, make it write out a CSV file and import that with LOAD DATA INFILE.  Keep those big fat log files out of the database.  The database is usually the most expensive and hardest-to-scale component in your system -- don't waste resources.</p>
<p>Another benefit of this is the chance to parallelize.  As you know, MySQL doesn't do intra-query parallelization, so ETL jobs written to rely on SQL tend to get really bogged down.  In contrast, moving the processing outside the database lets you parallelize trivially.</p>
<p>If you need to analyze the non-aggregated data, you can store it on the filesystem and write custom scripts to do special-purpose tasks on it.  Storing a little meta-data about each file can help a lot.  Store the ranges of values for various attributes, for example; or the presence or absence of values.  You can put these into the database in a little meta-table.  Then your script can figure out which files it can ignore.  What we're doing here starts to look like a hillbilly version of Infobright, which I'll talk about later.</p>
<p>Alternately, you can store the atomic data as CSV files and use the CSV engine so you have an SQL interface to it (the meta-tables are still a valid approach here!).  This is an easy way to bypass the hard-to-scale database server for the initial insertion, because you can write CSV files with any programming language.  Naturally, CSV files don't store as compactly on disk as [Compressed] MyISAM or Archive.</p>
<p>These are just some ideas I'm throwing around -- the point is to think outside the box, even to think of things that seem "less advanced" than using a database.</p>
<p><strong>Sharding and Partitioning</strong></p>
<p>Sharding is inevitable if your write workload exceeds the capacity of a single server (or if you're using replication, the capacity of a single slave).  Sharding can also help you avoid massive tables that are too big to maintain.  If you know you'll get there, it can change the lifecycle of your application in advance.</p>
<p>What about partitioning in MySQL 5.1?  I know there are some cases when it can help a lot, and we've proven that with our customers.  But you still have to think about how to avoid enormous tables that are hard to maintain, back up, and restore.  And the partitioning functionality is not done yet and not fully integrated into the server, so I expect to find a lot more bugs and annoyances.  There are already inconvenient limitations on some key parts of partitioning, such as maintenance and repair commands, that essentially negate the benefits of partitioning for those operations.  An finally, it doesn't save you from the downtime caused by ALTER TABLE -- a typical reason to think about master-master with failover and failback for maintenance.  As with anything, it's a cost-benefit equation.  What are your priorities?  Choose the solution that meets them.</p>
<p><strong>Be Careful With Data Integrity</strong></p>
<p>When you're storing several levels of aggregation, and there's denormalization, you need to be scrupulous about data cleanliness, because it's really hard to fix things up later.  If your data is coming from a partner site, and you upload bad data there, you'll be getting bad data back for a long time.  And every time you have some incremental job to update the aggregates, you're exposed to that bad data again.</p>
<p>Any inconsistencies in the atomic data tend to get magnified as it gets aggregated, because you suddenly have a single row created from many rows, and if the many rows don't match completely, the single one doesn't know what data should live in it.  And this only gets harder to resolve as you get more levels of aggregations.</p>
<p><strong>Watch Out For The Long Tail</strong></p>
<p>People talk about the long tail and how you can focus on optimizing the short head.  It's the classic 80-20 rule.  Maybe 80% of your ad impressions are on 20% of your ads!  Hooray!  But don't forget that if you're aggregating per-day, an ad that gets a million impressions takes one row, and an ad that gets one impression takes exactly the same: one row.  An impression per day becomes a fixed overhead of storage size.  So, you actually have as many rows as you have unique ads per day.  Viewed this way, suddenly you start to hate the ads that occasionally get an impression.  They're so wasteful!</p>
<p>It's easy to flip back and forth between viewpoints on this and get distracted into making a mistake.  Watch out when you do your capacity planning.  Don't get fooled into calculating the wrong thing.</p>
<p><strong>Be Creative With Table Structures</strong></p>
<p>Suppose you have some yes/no fact about an ad impression, such as whether it was a blue ad (whatever that means.)  You start out with this:</p>
<div class="igBar"><span id="lsql-41"><a href="#" onclick="javascript:showPlainTxt('sql-41'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-41">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> ads_by_day_by_blueness <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; day date <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; ad int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; is_blue tinyint <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; clicks int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; impressions int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">....</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color:#006600; font-weight:bold;">&#40;</span>day, ad, is_blue<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>What can we improve here?  Especially assuming that there are indexes other than the primary key, we can shrink the primary key's width:</p>
<div class="igBar"><span id="lsql-42"><a href="#" onclick="javascript:showPlainTxt('sql-42'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-42">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> ads_by_day_by_blueness <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; day date <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; ad int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; clicks int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; impressions int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; blue_clicks int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; blue_impressions int <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">....</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color:#006600; font-weight:bold;">&#40;</span>day, ad<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>There are a couple of ways to handle this now.  You can have the clicks column record the total, and the blue_clicks column record only blue clicks; to find out non-blue clicks you subtract one from the other.  Or you can have the blue clicks and non-blue clicks stored, and to get the totals you add them.</p>
<p>Did this gain us anything?  We dropped one column, and we just moved those other values around to store them "next, to in the same row" instead of "below, in the next row."  So we're storing all the same data, right?</p>
<p>Logically, yes; physically, no.  Those values that we pivoted up beside their neighbors will share a set of primary key columns.  And not only will every index be a little narrower, the table will now contain only half as many rows.  That will make the indexes less than half the size.  In real life this technique often makes the table+index much less than half the size.  You have to write a little more complex queries, but that's often justified by a large reduction in table size.</p>
<p>I sort of stumbled upon this idea one day. I have no idea what this technique might be called, so I call it dog-earing the table (somehow the image of putting columns next to each other makes me think of putting cards next to each other and shoving).</p>
<p><strong>Archive</strong></p>
<p>If you don't need data anymore, move it away or get rid of it.  I wrote a <a href="http://www.xaprb.com/blog/2007/06/13/archive-strategies-for-oltp-servers-part-1/">three-part article on data archiving</a> on my own blog a while back.  The benefits of purging and archiving data can be dramatic.</p>
<p><strong>Take It Easy On Replication</strong></p>
<p>Building aggregated tables is hard work for the database server.  If you do it on the master with INSERT..SELECT queries, it will propagate to the slaves and it'll be hard work there too, assuming you use statement-based replication.</p>
<p>You can save that work by either using MySQL 5.1's row-based replication, or in MySQL 5.0 and earlier, doing the work on a slave, then piping the results back up to the master with LOAD DATA INFILE, which kind of emulates row-based replication in a way.</p>
<p>When you're updating big aggregate tables, don't work with giant chunks of them at once.  If there's any possible way, do it in manageable bits.  A day at a time, for example.</p>
<p>There are a lot of other ways you can make replication faster.  I wrote a lot about this in our book, which is linked from the sidebar above.</p>
<p><strong>Don't Assume Traditional Methods Will Save You</strong></p>
<p>What you're really doing here is building a data warehouse.  So you may think you should use traditional DW methods, like star schemas.  The problem is that MySQL doesn't tend to perform well on a data warehousing workload.  The nested-loop joins are not all that fast on big joins; the query optimizer can sometimes pick bad plans when you have a lot of joins between fact and dimension tables, and so on.  With careful tweaking, many of these things can be overcome, but how much time do you have?  And the gains are simply limited by some of MySQL's weaknesses in some cases.</p>
<p>Not only that, but star schemas are not intended to be fast.  The star schema is essentially "I admit defeat and accept table scans as a fact of life."  <a href="http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/">Table scans can be better than the alternative</a>, if the alternatives are limited, but they're still not what you need unless you're okay with long queries that read a lot of rows -- MySQL can't handle too many of those at once.</p>
<p>Aside from star schemas, another tactic I see people try a lot is to build "flexible schemas" with tables that contain name-value pairs or something similar.  The thought is that you can make the application believe it has a custom table, which is really constructed behind the scenes from the name-value tables in a complex query with many joins.  I have never seen this approach scale well.</p>
<p><strong>Use The Best Technologies You Can</strong></p>
<p>MySQL is not the end-all and be-all.  If you're familiar with it and it can serve you reasonably well, it's fine to use it for things that it's not 100% optimal for.  But if the costs of doing that are going to outweigh the costs of using another solution, then look at other solutions.</p>
<p>One that holds promise is <a href="http://www.infobright.org/">Infobright</a>.  While I have not evaluated their technology in depth, I think it merits a good look.  I had the chance at <a href="http://www.opensqlcamp.org/">OpenSQL Camp</a> to talk to Alex Esterkin and see him present on it, and based on that exposure, I think they are doing a lot of things right.  When I know enough to have a real opinion (or when other Percona people get to it before I do!) you'll see results on this blog.</p>
<p>Another is <a href="http://www.kickfire.com/">Kickfire</a> -- also something I have not had a chance to properly evaluate.  And there are others, and there will continue to be more.  Finally, <a href="http://www.postgresql.org/">PostgreSQL</a> is clearly better for some workloads out-of-the-box than MySQL is, especially for more complex queries.  Percona is not tied to MySQL, although we're most famous for our knowledge about it.  When another tool is the right one, we use it.</p>
<p>Have you thought about using something besides a database?  You have your choice of buzzwords these days.  Hadoop is a big one.  But beware of falling into the trap of brute-forcing a solution that really needs to be solved with intelligent engineering, instead of massive resources.</p>
<p><strong>Conclusion</strong></p>
<p>This article has been an overview of some of the tactics I've used to successfully scale large click-processing and other types of event-analysis databases.  In some cases I've been able to avoid sharding for a long time and run on many fewer disk drives with much less memory, or even with 10-15x fewer servers.  Clever application design, and a holistic approach, are absolutely necessary.  You can't look to the database to solve everything -- you have to give it all the help you can.  Hopefully it's useful to you, too!</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/#comments">9 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/&amp;title=High-Performance Click Analysis with MySQL" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/&amp;title=High-Performance Click Analysis with MySQL" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/&amp;title=High-Performance Click Analysis with MySQL" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/&amp;T=High-Performance Click Analysis with MySQL" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/&amp;title=High-Performance Click Analysis with MySQL" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/12/22/high-performance-click-analysis-with-mysql/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>How expensive is a WHERE clause in MySQL?</title>
		<link>http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 12:42:54 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[optimizer]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=517</guid>
		<description><![CDATA[This is a fun question I've been wanting to test for some time.  How much overhead does a trivial WHERE clause add to a MySQL query?  To find out, I set my InnoDB buffer pool to 256MB and created a table that's large enough to test, but small enough to fit wholly in memory:
PLAIN TEXT
SQL:




CREATE [...]]]></description>
			<content:encoded><![CDATA[<p>This is a fun question I've been wanting to test for some time.  How much overhead does a trivial WHERE clause add to a MySQL query?  To find out, I set my InnoDB buffer pool to 256MB and created a table that's large enough to test, but small enough to fit wholly in memory:</p>
<div class="igBar"><span id="lsql-47"><a href="#" onclick="javascript:showPlainTxt('sql-47'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-47">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`t`</span> <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ff0000;">`a`</span> date <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span> ENGINE=InnoDB <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET=latin1;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> t<span style="color:#006600; font-weight:bold;">&#40;</span>a<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color:#006600; font-weight:bold;">&#40;</span>current_date<span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> t <span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> t; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I repeated the last statement until it got slow enough that I thought I could do a reasonable test; at this point there were 8388608 rows.  I then optimized the table and restarted MySQL.  The table ended up at 237MB.</p>
<p>Now let's see how long a table scan with no WHERE clause takes:</p>
<div class="igBar"><span id="lsql-48"><a href="#" onclick="javascript:showPlainTxt('sql-48'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-48">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> sql_no_cache count<span style="color:#006600; font-weight:bold;">&#40;</span>*<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> t;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| count<span style="color:#006600; font-weight:bold;">&#40;</span>*<span style="color:#006600; font-weight:bold;">&#41;</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">8388608</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">----------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">5</span>.<span style="color: #cc66cc;color:#800000;">23</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>I repeated this ten times and averaged the time: 5.01 seconds, ranging from 4.83 to 5.17 seconds.  Next I ran it with a trivial WHERE clause:</p>
<div class="igBar"><span id="lsql-49"><a href="#" onclick="javascript:showPlainTxt('sql-49'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-49">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> count<span style="color:#006600; font-weight:bold;">&#40;</span>*<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> t <span style="color: #993333; font-weight: bold;">WHERE</span> a = current_date; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>(Pop quiz: do I need SQL_NO_CACHE on this query?)  The average execution time for this query is 7.96, ranging from 7.65 to 8.15 seconds.  So apparently the overhead of the WHERE clause is about 2.95 seconds, or 351 nanoseconds per row.  It doesn't seem like much per row, but it adds up to about an extra 60% cost for the query.  If I add another WHERE clause,</p>
<div class="igBar"><span id="lsql-50"><a href="#" onclick="javascript:showPlainTxt('sql-50'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-50">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> count<span style="color:#006600; font-weight:bold;">&#40;</span>*<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> t <span style="color: #993333; font-weight: bold;">WHERE</span> a = current_date <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #993333; font-weight: bold;">LEFT</span><span style="color:#006600; font-weight:bold;">&#40;</span>a, <span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> = <span style="color: #ff0000;">'2008-10-29'</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>The average time is 9.39 seconds, or an added 87% overhead.</p>
<p>It would be interesting, in an academic kind of way, to test different data types and various complexities of WHERE clauses, but I'm not really interested enough to spend much time on it.  I just wondered whether the WHERE clause would even be noticeable.  This test doesn't really reveal anything you can do to make your queries faster -- you usually can't optimize the WHERE clause itself, only the way that the MySQL optimizer chooses to apply the clause to indexes.  (However, as I found out some time ago, <a href="http://www.xaprb.com/blog/2006/06/12/benchmarks-for-date-operations-in-mysql/">some date functions are faster than others</a>.  That would be interesting to look into more.)</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/#comments">15 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/&amp;title=How expensive is a WHERE clause in MySQL?" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/&amp;title=How expensive is a WHERE clause in MySQL?" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/&amp;title=How expensive is a WHERE clause in MySQL?" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/&amp;T=How expensive is a WHERE clause in MySQL?" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/&amp;title=How expensive is a WHERE clause in MySQL?" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/10/31/how-expensive-is-a-where-clause-in-mysql/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>How adding another table to JOIN can improve performance ?</title>
		<link>http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 05:10:50 +0000</pubDate>
		<dc:creator>peter</dc:creator>
				<category><![CDATA[bugs]]></category>
		<category><![CDATA[optimizer]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/?p=454</guid>
		<description><![CDATA[JOINs are expensive and it most typical the fewer tables (for the same database) you join the better performance you will get.   As for any rules there are however exceptions  
The one I'm speaking about comes from the issue with MySQL optimizer stopping using further index key parts as soon as there [...]]]></description>
			<content:encoded><![CDATA[<p>JOINs are expensive and it most typical the fewer tables (for the same database) you join the better performance you will get.   As for any rules there are however exceptions <img src='http://www.mysqlperformanceblog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The one I'm speaking about comes from the issue with MySQL optimizer stopping using further index key parts as soon as there is a range clause on the previous key part.   So if you have <em>INDEX(A,B)</em>  and have a where clause  <em>A BETWEEN 5 and 10  AND B=6</em>   only the first part (A) of the index will be used which can be seriously affect performance.  Of course in this example you can use index (B,A) but there are many similar cases when it is not possible.</p>
<p>I have <a href="http://www.mysqlperformanceblog.com/2006/08/10/using-union-to-implement-loose-index-scan-to-mysql/">described </a> couple of solutions to this problem -  using IN list instead of range or UNION  which however require rather serious application changes and also can result in huge IN lists and suboptimal execution for large ranges. </p>
<p>Lets take a look at very typical reporting query which queries data for date range for multiple of groups (these can be devices, pages, users .... etc)</p>
<div class="igBar"><span id="lsql-57"><a href="#" onclick="javascript:showPlainTxt('sql-57'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-57">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`info`</span> <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`id`</span> int<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`d`</span> date <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`group_id`</span> int<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`events`</span> int<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color:#006600; font-weight:bold;">&#41;</span>,</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`d`</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">`d`</span>,<span style="color: #ff0000;">`group_id`</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span> ENGINE=MyISAM <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>=<span style="color: #cc66cc;color:#800000;">18007591</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET=latin1</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info <span style="color: #993333; font-weight: bold;">WHERE</span> d <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'2007-01-01'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'2007-01-31'</span>&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span>,<span style="color: #cc66cc;color:#800000;">20</span>,<span style="color: #cc66cc;color:#800000;">30</span>,<span style="color: #cc66cc;color:#800000;">40</span>,<span style="color: #cc66cc;color:#800000;">50</span>,<span style="color: #cc66cc;color:#800000;">60</span>,<span style="color: #cc66cc;color:#800000;">70</span>,<span style="color: #cc66cc;color:#800000;">80</span>,<span style="color: #cc66cc;color:#800000;">90</span>,<span style="color: #cc66cc;color:#800000;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------------+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------------+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;color:#800000;">3289092</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------------+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">1</span>.<span style="color: #cc66cc;color:#800000;">04</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info <span style="color: #993333; font-weight: bold;">WHERE</span> d <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'2007-01-01'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'2007-01-31'</span>&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span>,<span style="color: #cc66cc;color:#800000;">20</span>,<span style="color: #cc66cc;color:#800000;">30</span>,<span style="color: #cc66cc;color:#800000;">40</span>,<span style="color: #cc66cc;color:#800000;">50</span>,<span style="color: #cc66cc;color:#800000;">60</span>,<span style="color: #cc66cc;color:#800000;">70</span>,<span style="color: #cc66cc;color:#800000;">80</span>,<span style="color: #cc66cc;color:#800000;">90</span>,<span style="color: #cc66cc;color:#800000;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span> \G</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: info</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: d</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: d</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">7</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">355213</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As you can see from the EXPLAIN this query is expected to analyze over 300.000 of rows which is relatively fast for this (in memory) table but  will become unacceptable as soon as you get to do random disk IO.</p>
<p>Note this is also interesting case of EXPLAIN being wrong - it shows key_len=7 which corresponds to the full key while only first key part is used. </p>
<p>Let us now replace the range with IN list in this query:</p>
<div class="igBar"><span id="lsql-58"><a href="#" onclick="javascript:showPlainTxt('sql-58'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-58">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info <span style="color: #993333; font-weight: bold;">WHERE</span> d <span style="color: #993333; font-weight: bold;">IN</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">'2007-01-01'</span>,<span style="color: #ff0000;">'2007-01-02'</span>,<span style="color: #ff0000;">'2007-01-03'</span>,<span style="color: #ff0000;">'2007-01-04'</span>,<span style="color: #ff0000;">'2007-01-05'</span>,<span style="color: #ff0000;">'2007-01-06'</span>,<span style="color: #ff0000;">'2007-01-07'</span>,<span style="color: #ff0000;">'2007-01-08'</span>,<span style="color: #ff0000;">'2007-01-09'</span>,<span style="color: #ff0000;">'2007-01-10'</span>,<span style="color: #ff0000;">'2007-01-11'</span>,<span style="color: #ff0000;">'2007-01-12'</span>,<span style="color: #ff0000;">'2007-01-13'</span>,<span style="color: #ff0000;">'2007-01-14'</span>,<span style="color: #ff0000;">'2007-01-15'</span>,<span style="color: #ff0000;">'2007-01-16'</span>,<span style="color: #ff0000;">'2007-01-17'</span>,<span style="color: #ff0000;">'2007-01-18'</span>,<span style="color: #ff0000;">'2007-01-19'</span>,<span style="color: #ff0000;">'2007-01-20'</span>,<span style="color: #ff0000;">'2007-01-21'</span>,<span style="color: #ff0000;">'2007-01-22'</span>,<span style="color: #ff0000;">'2007-01-23'</span>,<span style="color: #ff0000;">'2007-01-24'</span>,<span style="color: #ff0000;">'2007-01-25'</span>,<span style="color: #ff0000;">'2007-01-26'</span>,<span style="color: #ff0000;">'2007-01-27'</span>,<span style="color: #ff0000;">'2007-01-28'</span>,<span style="color: #ff0000;">'2007-01-29'</span>,<span style="color: #ff0000;">'2007-01-30'</span>,<span style="color: #ff0000;">'2007-01-31'</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span>,<span style="color: #cc66cc;color:#800000;">20</span>,<span style="color: #cc66cc;color:#800000;">30</span>,<span style="color: #cc66cc;color:#800000;">40</span>,<span style="color: #cc66cc;color:#800000;">50</span>,<span style="color: #cc66cc;color:#800000;">60</span>,<span style="color: #cc66cc;color:#800000;">70</span>,<span style="color: #cc66cc;color:#800000;">80</span>,<span style="color: #cc66cc;color:#800000;">90</span>,<span style="color: #cc66cc;color:#800000;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span> \G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: info</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: d</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: d</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">7</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">3681</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">01</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info <span style="color: #993333; font-weight: bold;">WHERE</span> d <span style="color: #993333; font-weight: bold;">IN</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">'2007-01-01'</span>,<span style="color: #ff0000;">'2007-01-02'</span>,<span style="color: #ff0000;">'2007-01-03'</span>,<span style="color: #ff0000;">'2007-01-04'</span>,<span style="color: #ff0000;">'2007-01-05'</span>,<span style="color: #ff0000;">'2007-01-06'</span>,<span style="color: #ff0000;">'2007-01-07'</span>,<span style="color: #ff0000;">'2007-01-08'</span>,<span style="color: #ff0000;">'2007-01-09'</span>,<span style="color: #ff0000;">'2007-01-10'</span>,<span style="color: #ff0000;">'2007-01-11'</span>,<span style="color: #ff0000;">'2007-01-12'</span>,<span style="color: #ff0000;">'2007-01-13'</span>,<span style="color: #ff0000;">'2007-01-14'</span>,<span style="color: #ff0000;">'2007-01-15'</span>,<span style="color: #ff0000;">'2007-01-16'</span>,<span style="color: #ff0000;">'2007-01-17'</span>,<span style="color: #ff0000;">'2007-01-18'</span>,<span style="color: #ff0000;">'2007-01-19'</span>,<span style="color: #ff0000;">'2007-01-20'</span>,<span style="color: #ff0000;">'2007-01-21'</span>,<span style="color: #ff0000;">'2007-01-22'</span>,<span style="color: #ff0000;">'2007-01-23'</span>,<span style="color: #ff0000;">'2007-01-24'</span>,<span style="color: #ff0000;">'2007-01-25'</span>,<span style="color: #ff0000;">'2007-01-26'</span>,<span style="color: #ff0000;">'2007-01-27'</span>,<span style="color: #ff0000;">'2007-01-28'</span>,<span style="color: #ff0000;">'2007-01-29'</span>,<span style="color: #ff0000;">'2007-01-30'</span>,<span style="color: #ff0000;">'2007-01-31'</span><span style="color:#006600; font-weight:bold;">&#41;</span>&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span>,<span style="color: #cc66cc;color:#800000;">20</span>,<span style="color: #cc66cc;color:#800000;">30</span>,<span style="color: #cc66cc;color:#800000;">40</span>,<span style="color: #cc66cc;color:#800000;">50</span>,<span style="color: #cc66cc;color:#800000;">60</span>,<span style="color: #cc66cc;color:#800000;">70</span>,<span style="color: #cc66cc;color:#800000;">80</span>,<span style="color: #cc66cc;color:#800000;">90</span>,<span style="color: #cc66cc;color:#800000;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;color:#800000;">3289092</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">02</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>So we get same result but approximately 50 times faster.   In this report we had just one month worth of data - what if you  would have a year ? 5 years ? What if you get say thousands of groups at the same time ?   Performing such query MySQL has to build (and do lookups) for all combinations which is 31*10=310 in this case. But if it gets to hundreds of thousands this method starts to break (and newer MySQL versions will stop using this optimization method if there are too many combinations to check).</p>
<p>Instead you could use JOIN to get list of days matching range from some pre-generated table and use the join to retrieve the rows from original table:</p>
<div class="igBar"><span id="lsql-59"><a href="#" onclick="javascript:showPlainTxt('sql-59'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-59">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SHOW</span> <span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> dl \G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">TABLE</span>: dl</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span>: <span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`dl`</span> <span style="color:#006600; font-weight:bold;">&#40;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #ff0000;">`myday`</span> date <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>&nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #ff0000;">`myday`</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#41;</span> ENGINE=MyISAM <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET=latin1</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span>&nbsp; * <span style="color: #993333; font-weight: bold;">FROM</span> dl <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;color:#800000;">5</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">------------+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| myday&nbsp; &nbsp; &nbsp; |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">------------+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #cc66cc;color:#800000;">2001</span>-<span style="color: #cc66cc;color:#800000;">01</span>-<span style="color: #cc66cc;color:#800000;">01</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #cc66cc;color:#800000;">2001</span>-<span style="color: #cc66cc;color:#800000;">01</span>-<span style="color: #cc66cc;color:#800000;">02</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #cc66cc;color:#800000;">2001</span>-<span style="color: #cc66cc;color:#800000;">01</span>-<span style="color: #cc66cc;color:#800000;">03</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #cc66cc;color:#800000;">2001</span>-<span style="color: #cc66cc;color:#800000;">01</span>-<span style="color: #cc66cc;color:#800000;">04</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #cc66cc;color:#800000;">2001</span>-<span style="color: #cc66cc;color:#800000;">01</span>-<span style="color: #cc66cc;color:#800000;">05</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">------------+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">5</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info,dl <span style="color: #993333; font-weight: bold;">WHERE</span> myday <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'2007-01-01'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'2007-01-31'</span> <span style="color: #993333; font-weight: bold;">AND</span> myday=d <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span>,<span style="color: #cc66cc;color:#800000;">20</span>,<span style="color: #cc66cc;color:#800000;">30</span>,<span style="color: #cc66cc;color:#800000;">40</span>,<span style="color: #cc66cc;color:#800000;">50</span>,<span style="color: #cc66cc;color:#800000;">60</span>,<span style="color: #cc66cc;color:#800000;">70</span>,<span style="color: #cc66cc;color:#800000;">80</span>,<span style="color: #cc66cc;color:#800000;">90</span>,<span style="color: #cc66cc;color:#800000;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span> \G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: dl</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">3</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">30</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">INDEX</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">2</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: info</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: d</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: d</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">7</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">355213</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">2</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As you can see it does not work while I know I used exactly this trick  to optimize some nasty queries.<br />
It looks like equality propagation is working here (note the number of rows for second table in join is estimated  same in original query) and we get the range clause on "info" table instead nested loops join - exactly what we tried to avoid. </p>
<p>It is easy to block equality propagation by using some trivial function:</p>
<div class="igBar"><span id="lsql-60"><a href="#" onclick="javascript:showPlainTxt('sql-60'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-60">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info,dl <span style="color: #993333; font-weight: bold;">WHERE</span> myday <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'2007-01-01'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'2007-01-31'</span>&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> d=date<span style="color:#006600; font-weight:bold;">&#40;</span>myday<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span>,<span style="color: #cc66cc;color:#800000;">20</span>,<span style="color: #cc66cc;color:#800000;">30</span>,<span style="color: #cc66cc;color:#800000;">40</span>,<span style="color: #cc66cc;color:#800000;">50</span>,<span style="color: #cc66cc;color:#800000;">60</span>,<span style="color: #cc66cc;color:#800000;">70</span>,<span style="color: #cc66cc;color:#800000;">80</span>,<span style="color: #cc66cc;color:#800000;">90</span>,<span style="color: #cc66cc;color:#800000;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span> \G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: dl</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">3</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">30</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">INDEX</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">2</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: info</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: ref</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: d</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: d</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">3</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: func</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">17990</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">2</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>So we stopped equality propagation but now have another problem - for some reason MySQL decides to only do "ref" on the date only instead of using range on day and list of groups for each join iteration.<br />
This does not make sense but this is how it is. </p>
<p>I also tried to increase cardinality by having all rows to have different group_id and it still does not work.</p>
<p>The trick however does work if you have just one group_id (and in this case you do not even need  to trick around equity propagation to make it work)</p>
<div class="igBar"><span id="lsql-61"><a href="#" onclick="javascript:showPlainTxt('sql-61'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-61">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> info,dl <span style="color: #993333; font-weight: bold;">WHERE</span> myday <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'2007-01-01'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'2007-01-31'</span>&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> d=myday <span style="color: #993333; font-weight: bold;">AND</span> group_id <span style="color: #993333; font-weight: bold;">IN</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> \G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: dl</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">3</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">30</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">INDEX</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">2</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: info</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: ref</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: d</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: d</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">7</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: test.dl.myday,const</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">18</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra:</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">2</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>For original query form with single group_id query was taking <strong>0.95 sec</strong>.  The query with BETWEEN range replaced with IN list  was instant  <strong>0.00 sec</strong> same as the query using join with day list table.</p>
<p>So we finally managed to get better performance by joining data to yet another table though why it does not work for multiple group remains question to check with MySQL Optimizer team <img src='http://www.mysqlperformanceblog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>UPDATE:  </strong> I just heard back from Igor Babaev saying it was designed this way (because the first component can run through very many values). The second component is simply not considered for range unless it is equality.    You always have something to learn about MySQL Optimizer gotchas <img src='http://www.mysqlperformanceblog.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>At the same time I figured out how to make MySQL Optimizer to do what we want to do - Just add yet another table to the join so the info table just has bunch of ref lookups:</p>
<div class="igBar"><span id="lsql-62"><a href="#" onclick="javascript:showPlainTxt('sql-62'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-62">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> g;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-----+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| gr&nbsp; |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-----+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">10</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">20</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">30</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">40</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">50</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">60</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">70</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">80</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">|&nbsp; <span style="color: #cc66cc;color:#800000;">90</span> |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #cc66cc;color:#800000;">100</span> |</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-----+</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">10</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> sum<span style="color:#006600; font-weight:bold;">&#40;</span>events<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> g,info,dl <span style="color: #993333; font-weight: bold;">WHERE</span> myday <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'2007-01-01'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'2007-01-31'</span> <span style="color: #993333; font-weight: bold;">AND</span> myday=d <span style="color: #993333; font-weight: bold;">AND</span> group_id=g.gr \G</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: dl</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: range</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">3</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">30</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">INDEX</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">2</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: g</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: <span style="color: #993333; font-weight: bold;">INDEX</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: <span style="color: #993333; font-weight: bold;">PRIMARY</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">4</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">10</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">INDEX</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">3</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;id: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; select_type: SIMPLE</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">TABLE</span>: info</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;type: ref</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">possible_keys: d</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">KEY</span>: d</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; key_len: <span style="color: #cc66cc;color:#800000;">7</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref: test.dl.myday,test.g.gr</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rows: <span style="color: #cc66cc;color:#800000;">18</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; Extra:</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #cc66cc;color:#800000;">3</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color: #cc66cc;color:#800000;">0</span>.<span style="color: #cc66cc;color:#800000;">00</span> sec<span style="color:#006600; font-weight:bold;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p> </p>
<p>This query looks very scary but in fact perform much better than original one.  In the real queries you can use table with ids just as we had table of days with a where clause instead of precreated table.</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by peter |
      <a href="http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/#comments">12 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/&amp;title=How adding another table to JOIN can improve performance ?" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/&amp;title=How adding another table to JOIN can improve performance ?" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/&amp;title=How adding another table to JOIN can improve performance ?" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/&amp;T=How adding another table to JOIN can improve performance ?" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/&amp;title=How adding another table to JOIN can improve performance ?" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/08/01/how-adding-another-table-to-join-can-improve-performance/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>The MySQL optimizer, the OS cache, and sequential versus random I/O</title>
		<link>http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/</link>
		<comments>http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/#comments</comments>
		<pubDate>Tue, 29 Apr 2008 02:18:38 +0000</pubDate>
		<dc:creator>Baron Schwartz</dc:creator>
				<category><![CDATA[optimizer]]></category>
		<category><![CDATA[storage engine]]></category>

		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/</guid>
		<description><![CDATA[In my post on estimating query completion time, I wrote about how I measured the performance on a join between a few tables in a typical star schema data warehousing scenario.
In short, a query that could take several days to run with one join order takes an hour with another, and the optimizer chose the [...]]]></description>
			<content:encoded><![CDATA[<p>In my post on <a href="http://www.mysqlperformanceblog.com/2008/04/22/how-to-estimate-query-completion-time-in-mysql/">estimating query completion time</a>, I wrote about how I measured the performance on a join between a few tables in a typical star schema data warehousing scenario.</p>
<p>In short, a query that could take several days to run with one join order takes an hour with another, and the optimizer chose the poorer of the two join orders.  Why is one join order so much slower than the other, and why did the optimizer not choose the faster one?  That's what this post is about.</p>
<p>Let's  start with the MySQL query optimizer.  The optimizer tries to choose the best join order based on its cost metric; it tries to estimate the cost for a query, then choose the query plan that has the lowest cost.  <strong>The unit of cost for the MySQL query optimizer is a single random 4k data page read</strong>.  In general, it's a pretty good metric, but it has one major weakness: the server doesn't know whether a read will be satisfied from the operating system cache, or whether it'll have to go to disk. (This distinction is abstracted away by the storage engine; the optimizer doesn't know how a given storage engine stores its data).</p>
<p>I'll try to omit the details and keep this clean.  Let's take a look at the tables.</p>
<div class="igBar"><span id="lsql-67"><a href="#" onclick="javascript:showPlainTxt('sql-67'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-67">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&amp;gt; <span style="color: #993333; font-weight: bold;">SHOW</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">STATUS</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'fact'</span>\G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Name: fact</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Engine: MyISAM</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Rows: <span style="color: #cc66cc;color:#800000;">147045493</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Avg_row_length: <span style="color: #cc66cc;color:#800000;">117</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Data_length: <span style="color: #cc66cc;color:#800000;">17217646764</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Index_length: <span style="color: #cc66cc;color:#800000;">11993816064</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&amp;gt; <span style="color: #993333; font-weight: bold;">SHOW</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">STATUS</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'dim1'</span>\G</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Name: dim1</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Engine: MyISAM</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Rows: <span style="color: #cc66cc;color:#800000;">453193</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Avg_row_length: <span style="color: #cc66cc;color:#800000;">122</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Data_length: <span style="color: #cc66cc;color:#800000;">55605116</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Index_length: <span style="color: #cc66cc;color:#800000;">93812736</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">mysql&amp;gt; <span style="color: #993333; font-weight: bold;">SHOW</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">STATUS</span> <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'dim2'</span>\G</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Name: dim2</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Engine: MyISAM</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Rows: <span style="color: #cc66cc;color:#800000;">811</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Avg_row_length: <span style="color: #cc66cc;color:#800000;">105</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Data_length: <span style="color: #cc66cc;color:#800000;">85368</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Index_length: <span style="color: #cc66cc;color:#800000;">154624</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>It's a big fact table and two fairly small dimension tables, which is normal.  Here is the query:</p>
<div class="igBar"><span id="lsql-68"><a href="#" onclick="javascript:showPlainTxt('sql-68'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-68">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">SELECT</span> fact.col1, min<span style="color:#006600; font-weight:bold;">&#40;</span>fact.col2<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> min_col2</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">FROM</span> fact, dim1, dim2</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">WHERE</span> fact.col4 = dim1.col4</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">AND</span> dim1.col3 &lt;&gt; <span style="color: #ff0000;">'hello world'</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">AND</span> dim2.col5 = <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">AND</span> fact.dim2_id = dim2.dim2_id</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">AND</span> fact.col2&gt; some_const</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> fact.col1 </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>There are indexes on all the columns in all the ways you'd expect: all the dimension columns are indexed on every table, and there's a separate index on every column in the WHERE clause.  Here's the query plan initially.</p>
<div class="igBar"><span id="lsql-69"><a href="#" onclick="javascript:showPlainTxt('sql-69'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-69">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">1</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">TABLE</span>: dim1</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">type: range</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">key_len: <span style="color: #cc66cc;color:#800000;">195</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">rows: <span style="color: #cc66cc;color:#800000;">18790</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">TEMPORARY</span>; <span style="color: #993333; font-weight: bold;">USING</span> filesort</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">2</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">TABLE</span>: fact</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">type: ref</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">key_len: <span style="color: #cc66cc;color:#800000;">4</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">rows: <span style="color: #cc66cc;color:#800000;">606</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">*************************** <span style="color: #cc66cc;color:#800000;">3</span>. row ***************************</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">TABLE</span>: dim2</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">type: eq_ref</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">key_len: <span style="color: #cc66cc;color:#800000;">2</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">rows: <span style="color: #cc66cc;color:#800000;">1</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>This query will run for days and never complete.  No one ever let it finish to see how long it would run.</p>
<p>How do I know it will run for days? Here's my train of thought:</p>
<ul>
<li>It's performing index lookups into the fact table, which is big.</li>
<li>An index lookup is a random I/O.</li>
<li>A modern disk can do about 100 random I/O's per second, as a rule of thumb.</li>
<li>If you do the math with the rows column in EXPLAIN, you realize that this equates to about 18790 * 606 = 11386740 I/O operations, assuming that the indexes are fully in memory.</li>
<li>When you divide this by 100 I/O operations per second, and then divide that by 86400 seconds in a day, you get about 2.6 days.</li>
</ul>
<p>Ouch!  That's slow.</p>
<p>Now let's look at the alternative: table-scan the fact table, and do index lookups in the two dimension tables.  MySQL doesn't want to choose this join order, so we'll force it with STRAIGHT_JOIN:</p>
<div class="igBar"><span id="lsql-70"><a href="#" onclick="javascript:showPlainTxt('sql-70'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">SQL:</span>
<div id="sql-70">
<div class="sql">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">STRAIGHT_JOIN</span>&nbsp; ....</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------+-----------+-----------+---------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| <span style="color: #993333; font-weight: bold;">TABLE</span> | type&nbsp; &nbsp; &nbsp; | rows&nbsp; &nbsp; &nbsp; | Extra&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------+-----------+-----------+---------------------------------+</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| fact&nbsp; | <span style="color: #993333; font-weight: bold;">ALL</span>&nbsp; &nbsp; &nbsp; &nbsp;| <span style="color: #cc66cc;color:#800000;">147367284</span> | <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">TEMPORARY</span>; <span style="color: #993333; font-weight: bold;">USING</span> filesort |</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| dim1&nbsp; | eq_ref&nbsp; &nbsp; | <span style="color: #cc66cc;color:#800000;">1</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">| dim2&nbsp; | eq_ref&nbsp; &nbsp; | <span style="color: #cc66cc;color:#800000;">1</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">+<span style="color: #808080; font-style: italic;">-------+-----------+-----------+---------------------------------+ </span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>As we saw in the previous post, which I linked at the top of this post, we can scan the fact table in less than an hour.  And it turns out that joining to the dimension tables doesn't slow the query perceptibly, because these tables are small and they stay in memory, in the OS cache.  (They don't get evicted from memory by the cache's LRU policy, because they are frequently used -- once per row in the fact table.  The LRU policy evicts old blocks from the fact table instead, which is perfect -- these blocks are used only once and not needed again, so they can be replaced).</p>
<p>The difference between the two queries -- 55 minutes and 2.6 days -- is basically the difference between scanning data sequentially on disk and random disk I/O.</p>
<p>So now you know why one join order is faster than the other.  But why didn't the optimizer know this, too?  The optimizer does know that random access is slower than sequential access, <strong>but it doesn't know that the dimension tables will stay in memory</strong>, and this is an important distinction.</p>
<p>Let's put ourselves into the mindset of the optimizer.  We'll assume that every join to the dimension tables will go to disk instead of being read from cache.  Now the STRAIGHT_JOIN becomes a table scan of about 313 sequential reads (150 million rows / 117 bytes per row / 4096 bytes per read), plus about 150 million random I/Os for the first dimension table, plus 150 million random I/Os for the second dimension table.  That's 300 million random I/O operations.</p>
<p>In contrast, the optimizer chose a plan that it thought would cause only 11.3 million random I/O operations.</p>
<p>The optimizer was being smart, given its lack of knowledge about the OS cache.  This is why an expert  is sometimes needed to provide the missing information.  If the MySQL optimizer were right and each of these had to go to disk, our STRAIGHT_JOIN plan would take more than a month to complete!  Good thing we know the difference between cache and disk!</p>
    <hr noshade style="margin:0;height:1px" />
    <p>Entry posted by Baron Schwartz |
      <a href="http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/#comments">14 comments</a></p>
    <p>Add to: <a href="http://del.icio.us/post?url=http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/&amp;title=The MySQL optimizer, the OS cache, and sequential versus random I/O" title="Bookmark this post on del.icio.us"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/delicious.png" alt="delicious" /></a> | <a href="http://digg.com/submit?phase=2&amp;url=http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/&amp;title=The MySQL optimizer, the OS cache, and sequential versus random I/O" title="Digg this post on Digg.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/digg.png" alt="digg" /></a> | <a href="http://reddit.com/submit?url=http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/&amp;title=The MySQL optimizer, the OS cache, and sequential versus random I/O" title="Submit this post on reddit.com"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/reddit.png" alt="reddit" /></a> | <a href="http://www.netscape.com/submit/?U=http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/&amp;T=The MySQL optimizer, the OS cache, and sequential versus random I/O" title="Vote for this article on Netscape"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/netscape.gif" alt="netscape" /></a> | <a href="http://www.google.com/bookmarks/mark?op=add&amp;bkmk=http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/&amp;title=The MySQL optimizer, the OS cache, and sequential versus random I/O" title="Add to Google Bookmarks"><img src="http://www.mysqlperformanceblog.com/wp-content/themes/boxy-but-gold/images/google.png" alt="Google Bookmarks" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlperformanceblog.com/2008/04/28/the-mysql-optimizer-the-os-cache-and-sequential-versus-random-io/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
