<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.0.12-alpha" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: How MySQL executes ORDER BY</title>
	<link>http://s.petrunia.net/blog/?p=24</link>
	<description>Random observations made while working on MySQL / MariaDB query optimizer</description>
	<pubDate>Sat, 04 Sep 2010 18:19:53 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.12-alpha</generator>

	<item>
		<title>by: Mikiya</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-56062</link>
		<pubDate>Thu, 09 Jul 2009 14:01:17 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-56062</guid>
					<description>Hi Sergey,

How is it going? :)

I might completely have misunderstood how NLJ works. It might be opposing. My comment below describes how it works now, doesn't it? I had a wrong idea like "it firstly scans the driving table. then it fetches the following tables in turn" The my previous wrong idea is very much like BKA, isn't it? BKA joins fetches all satisfied rows to the WHERE clauns from the driving table firstly, then fetches matching rows from the following table. Is this correct?</description>
		<content:encoded><![CDATA[<p>Hi Sergey,</p>
<p>How is it going? <img src='http://s.petrunia.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I might completely have misunderstood how NLJ works. It might be opposing. My comment below describes how it works now, doesn&#8217;t it? I had a wrong idea like &#8220;it firstly scans the driving table. then it fetches the following tables in turn&#8221; The my previous wrong idea is very much like BKA, isn&#8217;t it? BKA joins fetches all satisfied rows to the WHERE clauns from the driving table firstly, then fetches matching rows from the following table. Is this correct?
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Mikiya</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-45931</link>
		<pubDate>Tue, 17 Mar 2009 21:24:14 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-45931</guid>
					<description>Thank you for your reply. I'll copy your picture soon :)

I'm looking forward to that MRR+sort will be implemented.

Another thing what I want you to consider to implement in the future is an optimization for LIMIT clause. Currently, LIMIT will take effect after all JOIN and filesort is done. It's okay for the third example above. However, building a whole JOIN result might be unnecessary for first and second example. If LIMIT is evaluated earlier, roundtrips can be reduced dramatically in some cases.

Suppose that the query has "LIMIT 3" clause. For the first example, MySQL optimizer executes the query like below:

o Fetch all matching rows from tbl1 in index order.
o Fetch all matching rows from tbl2 and join.
o Fetch all matching rows from tbl3 and join.
o Limit rows and returns 3 rows to the client.

If MySQL optimizer has an alternative plan like below, it looks more efficient than now:

o Fetch the first row from tbl1 in index order.
o Fetch matching rows from tbl2 and join.
o Fetch matching rows from tbl3 and join.
o At this point the number of rows is less than 3, then continue.
o Fetch the next row from tbl1 in index order.
o Fetch matching rows from tbl2 and join.
o Fetch matching rows from tbl3 and join.
o At this point the number of rows is greater than or equal to 3, then returns 3 rows to the client.

I see many web applications use LIMIT clause with sort. Having a query plan like this may improve query performance in certain cases IMHO :)</description>
		<content:encoded><![CDATA[<p>Thank you for your reply. I&#8217;ll copy your picture soon <img src='http://s.petrunia.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I&#8217;m looking forward to that MRR+sort will be implemented.</p>
<p>Another thing what I want you to consider to implement in the future is an optimization for LIMIT clause. Currently, LIMIT will take effect after all JOIN and filesort is done. It&#8217;s okay for the third example above. However, building a whole JOIN result might be unnecessary for first and second example. If LIMIT is evaluated earlier, roundtrips can be reduced dramatically in some cases.</p>
<p>Suppose that the query has &#8220;LIMIT 3&#8243; clause. For the first example, MySQL optimizer executes the query like below:</p>
<p>o Fetch all matching rows from tbl1 in index order.<br />
o Fetch all matching rows from tbl2 and join.<br />
o Fetch all matching rows from tbl3 and join.<br />
o Limit rows and returns 3 rows to the client.</p>
<p>If MySQL optimizer has an alternative plan like below, it looks more efficient than now:</p>
<p>o Fetch the first row from tbl1 in index order.<br />
o Fetch matching rows from tbl2 and join.<br />
o Fetch matching rows from tbl3 and join.<br />
o At this point the number of rows is less than 3, then continue.<br />
o Fetch the next row from tbl1 in index order.<br />
o Fetch matching rows from tbl2 and join.<br />
o Fetch matching rows from tbl3 and join.<br />
o At this point the number of rows is greater than or equal to 3, then returns 3 rows to the client.</p>
<p>I see many web applications use LIMIT clause with sort. Having a query plan like this may improve query performance in certain cases IMHO <img src='http://s.petrunia.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: sergey</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-45455</link>
		<pubDate>Thu, 12 Mar 2009 18:39:35 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-45455</guid>
					<description>Mikiya,

With regards to MRR and ordering:

* MRR/NDB is capable of producing ordered output (it will sort if asked to).

* MyISAM/Maria/Falcon/InnoDB-MRR are incapable of producing records in any particular order. I agree that sometimes it could be faster to use MRR+sort  (especially since we don\'t need to sort the complete set, we\'ll need to only restore index ordering within each of the MRR passes).  That\'s just not implemented. We\'ve decided to be conservative and disable MRR (other, more agressive option was to force sort if MRR is used) 

you\'re welcome to cite/copy pictures.</description>
		<content:encoded><![CDATA[<p>Mikiya,</p>
<p>With regards to MRR and ordering:</p>
<p>* MRR/NDB is capable of producing ordered output (it will sort if asked to).</p>
<p>* MyISAM/Maria/Falcon/InnoDB-MRR are incapable of producing records in any particular order. I agree that sometimes it could be faster to use MRR+sort  (especially since we don\&#8217;t need to sort the complete set, we\&#8217;ll need to only restore index ordering within each of the MRR passes).  That\&#8217;s just not implemented. We\&#8217;ve decided to be conservative and disable MRR (other, more agressive option was to force sort if MRR is used) </p>
<p>you\&#8217;re welcome to cite/copy pictures.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Fernando Serer &#187; MySQL: algunos enlaces interesantes</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-44968</link>
		<pubDate>Sat, 07 Mar 2009 15:08:35 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-44968</guid>
					<description>[...] How MySQL executes ORDER BY [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] How MySQL executes ORDER BY [&#8230;]
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Mikiya</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-44792</link>
		<pubDate>Thu, 05 Mar 2009 21:42:01 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-44792</guid>
					<description>Hi Sergey,

I wonder why MRR is disabled when ordering is required. I guess getting rows using MRR then filesort() may perform better than disabling MRR in some cases, especially for remote storage engines like NDB, because filesourt() could be faster than round trips between indexes.

BTW, can I cite these your pictures and introduce in my blog to Japanese people? They're really nice and intuitive ;)</description>
		<content:encoded><![CDATA[<p>Hi Sergey,</p>
<p>I wonder why MRR is disabled when ordering is required. I guess getting rows using MRR then filesort() may perform better than disabling MRR in some cases, especially for remote storage engines like NDB, because filesourt() could be faster than round trips between indexes.</p>
<p>BTW, can I cite these your pictures and introduce in my blog to Japanese people? They&#8217;re really nice and intuitive <img src='http://s.petrunia.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: What does Using filesort mean in MySQL? &#124; MySQL Performance Blog</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-44788</link>
		<pubDate>Thu, 05 Mar 2009 20:07:44 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-44788</guid>
					<description>[...] by Baron Schwartz @ 1:36 pm :: optimizer &#160; &#160;Print This Post del.icio.us :: digg &#160; Comment RSS &#160;  Related posts: :MySQL Optimizer and Innodb Primary Key::MySQL Performance - eliminatingORDER BY function::MySQL: Followup on UNION for query optimization, Query profiling: &#160; [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] by Baron Schwartz @ 1:36 pm :: optimizer &nbsp; &nbsp;Print This Post del.icio.us :: digg &nbsp; Comment RSS &nbsp;  Related posts: :MySQL Optimizer and Innodb Primary Key::MySQL Performance - eliminatingORDER BY function::MySQL: Followup on UNION for query optimization, Query profiling: &nbsp; [&#8230;]
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Xaprb</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-7323</link>
		<pubDate>Wed, 05 Sep 2007 13:15:16 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-7323</guid>
					<description>Thanks Sergey.  I'll add this query as a test case to the visual explain tool.  This rule shouldn't be hard to implement.</description>
		<content:encoded><![CDATA[<p>Thanks Sergey.  I&#8217;ll add this query as a test case to the visual explain tool.  This rule shouldn&#8217;t be hard to implement.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: sergey</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-7252</link>
		<pubDate>Mon, 03 Sep 2007 22:15:07 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-7252</guid>
					<description>(note to self: make the comment input box here better, at the moment it looks like it was designed  for SMS messages:)</description>
		<content:encoded><![CDATA[<p>(note to self: make the comment input box here better, at the moment it looks like it was designed  for SMS messages:)
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: sergey</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-7251</link>
		<pubDate>Mon, 03 Sep 2007 22:12:42 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-7251</guid>
					<description>Hi Baron,
&gt; You say ‘Use filesort() on 1st non-constant table -&gt; “Using filesort” in the first row’. So even if the first table in the JOIN is a ‘const’ or ’system’, the “Using filesort” will appear there, though the filesort may actually happen in a later table?

Yes (and yes, this is counterintuitive and I hope we'll fix it at some point)


&gt; I’m having trouble finding a query that will produce such an EXPLAIN plan, so I hope this isn’t an obvious question. 

Here is an example:
mysql&gt; explain select * from const_tbl, t1, t2 where t1.b=const_tbl.a and t2.a=t1.a order by t1.a;
+----+-------------+-----------+--------+---------------+------+---------+------------+------+----------------+
&#124; id &#124; select_type &#124; table     &#124; type   &#124; possible_keys &#124; key  &#124; key_len &#124; ref        &#124; rows &#124; Extra          &#124;
+----+-------------+-----------+--------+---------------+------+---------+------------+------+----------------+
&#124;  1 &#124; SIMPLE      &#124; const_tbl &#124; system &#124; NULL          &#124; NULL &#124; NULL    &#124; NULL       &#124;    1 &#124; Using filesort &#124; 
&#124;  1 &#124; SIMPLE      &#124; t1        &#124; ALL    &#124; NULL          &#124; NULL &#124; NULL    &#124; NULL       &#124;   10 &#124; Using where    &#124; 
&#124;  1 &#124; SIMPLE      &#124; t2        &#124; ref    &#124; a             &#124; a    &#124; 5       &#124; test4.t1.a &#124;   11 &#124; Using where    &#124; 
+----+-------------+-----------+--------+---------------+------+---------+------------+------+----------------+
3 rows in set (0.01 sec)</description>
		<content:encoded><![CDATA[<p>Hi Baron,<br />
> You say ‘Use filesort() on 1st non-constant table -> “Using filesort” in the first row’. So even if the first table in the JOIN is a ‘const’ or ’system’, the “Using filesort” will appear there, though the filesort may actually happen in a later table?</p>
<p>Yes (and yes, this is counterintuitive and I hope we&#8217;ll fix it at some point)</p>
<p>> I’m having trouble finding a query that will produce such an EXPLAIN plan, so I hope this isn’t an obvious question. </p>
<p>Here is an example:<br />
mysql> explain select * from const_tbl, t1, t2 where t1.b=const_tbl.a and t2.a=t1.a order by t1.a;<br />
+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
| id | select_type | table     | type   | possible_keys | key  | key_len | ref        | rows | Extra          |<br />
+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
|  1 | SIMPLE      | const_tbl | system | NULL          | NULL | NULL    | NULL       |    1 | Using filesort |<br />
|  1 | SIMPLE      | t1        | ALL    | NULL          | NULL | NULL    | NULL       |   10 | Using where    |<br />
|  1 | SIMPLE      | t2        | ref    | a             | a    | 5       | test4.t1.a |   11 | Using where    |<br />
+&#8212;-+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;+&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;-+<br />
3 rows in set (0.01 sec)
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: sergey</title>
		<link>http://s.petrunia.net/blog/?p=24#comment-7246</link>
		<pubDate>Mon, 03 Sep 2007 20:16:08 +0000</pubDate>
		<guid>http://s.petrunia.net/blog/?p=24#comment-7246</guid>
					<description>Hi Roland, 
&gt; I’m curious…the relationship between GROUP BY and ORDER BY you are referring too, is that intrinsical? Or is it caused by MySQL’s non-standard commitment to return the resulset according to the order implied by the GROUP BY clause.

Both yes and no. I'm going to have this question sorted out (for myself too :-) in the mentioned forthcoming posts.

&gt; would it from the Server development’s point of view be more or less complex if MySQL would not commit itself to returning the set in the order implied by the GROUP BY clause?

It would be possible to skip the sorting step sometimes, but as long as we use current apporaches to handling GROUP BY, there will be close relationship between GROUP BY and ORDER BY processing. Again, I hope to cover this in the next posts.</description>
		<content:encoded><![CDATA[<p>Hi Roland,<br />
> I’m curious…the relationship between GROUP BY and ORDER BY you are referring too, is that intrinsical? Or is it caused by MySQL’s non-standard commitment to return the resulset according to the order implied by the GROUP BY clause.</p>
<p>Both yes and no. I&#8217;m going to have this question sorted out (for myself too <img src='http://s.petrunia.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  in the mentioned forthcoming posts.</p>
<p>> would it from the Server development’s point of view be more or less complex if MySQL would not commit itself to returning the set in the order implied by the GROUP BY clause?</p>
<p>It would be possible to skip the sorting step sometimes, but as long as we use current apporaches to handling GROUP BY, there will be close relationship between GROUP BY and ORDER BY processing. Again, I hope to cover this in the next posts.
</p>
]]></content:encoded>
				</item>
</channel>
</rss>
