<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[explain的误解 ]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Mon, 27 Oct 2008 10:43:06 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	<p>发现MySQL的explain还是很有迷惑性的。<br /><br />看下面两个sql的explain，(i,j)是tt的主键<br /></p><pre><br />mysql&gt; explain select * from tt where i between 3 and 5 and j = 4&#92;G<br />*************************** 1. row ***************************<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id: 1<br /> select_type: SIMPLE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table: tt<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type: range<br />possible_keys: PRIMARY<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key: PRIMARY<br />&nbsp;&nbsp;&nbsp;&nbsp; key_len: 8<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref: NULL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows: 8<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Extra: Using where; Using index<br />1 row in set (0.00 sec)<br /><br />mysql&gt; explain select * from tt where i &gt; 2 and i &lt; 6 and j = 4&#92;G<br />*************************** 1. row ***************************<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id: 1<br />&nbsp;&nbsp;select_type: SIMPLE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;table: tt<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: range<br />possible_keys: PRIMARY<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key: PRIMARY<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;key_len: 4<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ref: NULL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rows: 8<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Extra: Using where; Using index<br />1 row in set (0.00 sec)<br /></pre><br />看上去如果使用了between，那么MySQL可以用的索引的两列。但仔细的研究了一下，发现实际并不是这样。between 3 and 5可以写为(i&gt;3 or i=3) and (i&lt;5 or i=5)，是这两个等号使用了两列，而大于和小于的判断仍然是index扫描，只用了一列。<br /><br />再看另一个<br /><pre><br />mysql&gt; explain select * from tt where i in (3,4,5) and j=4&#92;G<br />*************************** 1. row ***************************<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id: 1<br /> select_type: SIMPLE<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table: tt<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type: range<br />possible_keys: PRIMARY<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; key: PRIMARY<br />&nbsp;&nbsp;&nbsp;&nbsp; key_len: 8<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ref: NULL<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows: 3<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Extra: Using where; Using index<br />1 row in set (0.00 sec)<br /></pre><br />这个才是真正用了两列，可以看到这里估计的行数是3，而刚才两个是8。用 show status 可以看得更清楚一些：<br /><pre><br />mysql&gt; show status like 'handler_read%';<br />+-----------------------+-------+<br />&#124; Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#124; Value &#124;<br />+-----------------------+-------+<br />&#124; Handler_read_first&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_next&nbsp;&nbsp;&nbsp;&nbsp; &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_prev&nbsp;&nbsp;&nbsp;&nbsp; &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_rnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_rnd_next &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />+-----------------------+-------+<br />6 rows in set (0.00 sec)<br /><br />mysql&gt; select * from tt where i in (3,4,5) and j=4;<br />+---+---+<br />&#124; i &#124; j &#124;<br />+---+---+<br />&#124; 3 &#124; 4 &#124;<br />+---+---+<br />1 row in set (0.00 sec)<br /><br />mysql&gt; show status like 'handler_read%';<br />+-----------------------+-------+<br />&#124; Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#124; Value &#124;<br />+-----------------------+-------+<br />&#124; Handler_read_first&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#124; 4&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_next&nbsp;&nbsp;&nbsp;&nbsp; &#124; 1&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_prev&nbsp;&nbsp;&nbsp;&nbsp; &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_rnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_rnd_next &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />+-----------------------+-------+<br />6 rows in set (0.00 sec)<br /><br />mysql&gt; select * from tt where i between 3 and 5 and j = 4;<br />+---+---+<br />&#124; i &#124; j &#124;<br />+---+---+<br />&#124; 3 &#124; 4 &#124;<br />+---+---+<br />1 row in set (0.00 sec)<br /><br />mysql&gt; show status like 'handler_read%';<br />+-----------------------+-------+<br />&#124; Variable_name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#124; Value &#124;<br />+-----------------------+-------+<br />&#124; Handler_read_first&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#124; 6&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_next&nbsp;&nbsp;&nbsp;&nbsp; &#124; 10&nbsp;&nbsp;&nbsp;&nbsp;&#124;<br />&#124; Handler_read_prev&nbsp;&nbsp;&nbsp;&nbsp; &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_rnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />&#124; Handler_read_rnd_next &#124; 0&nbsp;&nbsp;&nbsp;&nbsp; &#124;<br />+-----------------------+-------+<br />6 rows in set (0.00 sec)<br /></pre><br />后一个sql中有9次read_next_key，说明做了索引扫描。
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] explain的误解 ]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>