{"id":683,"date":"2015-03-29T18:32:12","date_gmt":"2015-03-29T16:32:12","guid":{"rendered":"http:\/\/dbahire.com\/?p=683"},"modified":"2019-08-27T11:59:46","modified_gmt":"2019-08-27T09:59:46","slug":"explain-minor-wishlist","status":"publish","type":"post","link":"https:\/\/jynus.com\/dbahire\/explain-minor-wishlist\/","title":{"rendered":"EXPLAIN minor wishlist"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/jynus.com\/dbahire\/wp-content\/uploads\/2015\/03\/explain_output.png\" alt=\"EXPLAIN output: filesort\" class=\"alignright size-full wp-image-693\" width=\"222\" height=\"215\">While we always want better performance and more and larger features for MySQL, those cannot just &#8220;magically appear&#8221; from one version to another, requiring deep architecture changes and lots of lines of code. However, there are sometimes smaller features and fixes that could be implemented by an intern or an external contributor, mainly at SQL layer, and that could make the MySQL ecosystem friendlier to newbies and non-experts. <strong>Making a piece of software easier to use is sometimes overlooked, but it is incredibly important<\/strong> -not everybody using MySQL is a DBA, and the more people adopting it, more people will be able to live from it, both upstream and as third party providers.<\/p>\n<p>Here it is my own personal list of fixes for EXPLAIN messages. If you are an experienced MySQL user you are probably aware of their meaning, but that doesn&#8217;t solve the problem for beginners. The reason why I am writing a blog post is to gather opinions on whether they seem important to you or not, and if my way of solving them seems reasonable so that we can submit them as feature requests.<\/p>\n<h2>EXPLAIN messages<\/h2>\n<p>As a MySQL instructor, the following case happens a lot with new students. You start with a command like this:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT b, c FROM test\\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: test\n         type: index\npossible_keys: NULL\n          key: b_c\n      key_len: 10\n          ref: NULL\n         rows: 4\n        Extra: Using index\n1 row in set (0.00 sec)<\/pre>\n<p>So, &#8220;<code>Using index<\/code>&#8221; means that an index is being used, right? No, in this case, the <code>type: index<\/code> is telling us that it is using an index for scanning or accessing the rows (because it is not a <code>type: ALL<\/code>&#8211; although we could get a full row scan and using the index for ordering or grouping them). The <code>Extra: Using index<\/code> indicates that the index is also used for retrieving the data, without actually needing to read the whole row. This is, as far as I know, commonly referred as Covering index. And that is exactly what I would like to see:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT b, c FROM test\\G -- edited output\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: test\n         type: index\npossible_keys: NULL\n          key: b_c\n      key_len: 10\n          ref: NULL\n         rows: 4\n        Extra: Using covering index\n1 row in set (0.00 sec)<\/pre>\n<p>or maybe:<\/p>\n<pre>        Extra: Covering index<\/pre>\n<p>Another common misunderstanding: <code>Using filesort<\/code>:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT * FROM test ORDER BY length(b)\\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: test\n         type: ALL\npossible_keys: NULL\n          key: NULL\n      key_len: NULL\n          ref: NULL\n         rows: 4\n        Extra: Using filesort\n1 row in set (0.00 sec)<\/pre>\n<p>At this level, I do not care if I am using filesort as an algorithm, and -if I am correct- since 5.6 can also use a priority queue for the sorting algorithm if the number of items is small. Additionally, the &#8220;file&#8221; in the filesort word can lead to confusion that this requires a temporary table on disk. I do not have a perfect alternative (please provide feedback), but maybe something like the following would be clearer:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT * FROM test ORDER BY length(b)\\G  -- edited output\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: test\n         type: ALL\npossible_keys: NULL\n          key: NULL\n      key_len: NULL\n          ref: NULL\n         rows: 4\n        Extra: Additional sort phase\n1 row in set (0.00 sec)<\/pre>\n<p>or maybe:<\/p>\n<pre>        Extra: Not using index for order-by<\/pre>\n<p>Another example would be:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT a FROM test WHERE b &gt; 3 and c = 3\\G\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: test\n         type: range\npossible_keys: b_c\n          key: b_c\n      key_len: 5\n          ref: NULL\n         rows: 1\n        Extra: Using index condition\n1 row in set (0.00 sec)<\/pre>\n<p>I understand that the developers didn&#8217;t want to confuse us with NDB&#8217;s pushed condition, but this output is quite misleading, too. It literally means that &#8220;the index condition is being used&#8221;, instead of &#8220;<a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/index-condition-pushdown-optimization.html\">ICP<\/a> is being used&#8221;. What about:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT a FROM test WHERE b &gt; 3 and c = 3\\G -- edited output\n*************************** 1. row ***************************\n           id: 1\n  select_type: SIMPLE\n        table: test\n         type: range\npossible_keys: b_c\n          key: b_c\n      key_len: 5\n          ref: NULL\n         rows: 1\n        Extra: Using index condition pushdown\n1 row in set (0.00 sec)<\/pre>\n<p>There are <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.7\/en\/explain-output.html\">many other expressions<\/a>, but those are the most annoying to me in terms of students&#8217; confusion.<\/p>\n<p>Would you agree with me? Would these changes break applications that may parse EXPLAIN output? What other small things would you change in MySQL output or error messages? I would specially would like to hear from MySQL beginners and people coming from other databases, as the more we have used to it, the more we get accustomed to MySQLisms.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While we always want better performance and more and larger features for MySQL, those cannot just &#8220;magically appear&#8221; from one version to another, requiring deep architecture changes and lots of lines of code. However, there are sometimes smaller features and<\/p>\n","protected":false},"author":1,"featured_media":693,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[302,327,329,331,455,285,333,335,337,339,304],"class_list":["post-683","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mysql","tag-explain","tag-filesort-en","tag-icp-en","tag-index-en","tag-mysql","tag-primary-en","tag-pushdown-en","tag-using-filesort-en","tag-using-index-en","tag-using-index-condition-en","tag-wishlist"],"_links":{"self":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/comments?post=683"}],"version-history":[{"count":19,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/683\/revisions"}],"predecessor-version":[{"id":1001,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/683\/revisions\/1001"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/media\/693"}],"wp:attachment":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/media?parent=683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/categories?post=683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/tags?post=683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}