{"id":702,"date":"2015-03-30T11:41:13","date_gmt":"2015-03-30T09:41:13","guid":{"rendered":"http:\/\/dbahire.com\/?p=702"},"modified":"2022-03-10T12:45:39","modified_gmt":"2022-03-10T11:45:39","slug":"pequena-lista-de-deseos-para-explain","status":"publish","type":"post","link":"https:\/\/jynus.com\/dbahire\/pequena-lista-de-deseos-para-explain\/","title":{"rendered":"Peque\u00f1a lista de deseos para EXPLAIN"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"\/dbahire\/wp-content\/uploads\/2015\/03\/explain_output.png\" alt=\"Salida de EXPLAIN: filesort\" class=\"alignright size-full wp-image-693\" width=\"222\" height=\"215\">Aunque siempre deseamos un mayor rendimiento y m\u00e1s y mejores caracter\u00edsticas para MySQL, estas no pueden aparecer &#8220;sin m\u00e1s&#8221; de una versi\u00f3n a otra, requiriendo profundos cambios en la arquitectura y muchas l\u00edneas de c\u00f3digo. Sin embargo, a veces hay peque\u00f1os cambios y arreglos que podr\u00edan implementarse por un becario o contribuidor externo, principalmente en la capa SQL, que podr\u00edan hacer el ecosistema de MySQL m\u00e1s amigable para novatos y no expertos. <strong>Hacer que un programa sea m\u00e1s f\u00e1cil de usar es muchas veces pasado de largo, pero es incre\u00edblemente importante<\/strong> -no todo el mundo usando MySQL es un administrador de bases de datos, y cuanta m\u00e1s gente lo adopte, m\u00e1s gente podr\u00e1 vivir de \u00e9l, tanto sus desarrolladores originales como proveedores externos.<\/p>\n<p>Esta es mi propia lista de arreglos para los mensajes de EXPLAIN. Si ya eres un usuario experimentado de MySQL probablemente ya conozcas su sugnificado, pero eso no resuelve el problema para los principiantes. La raz\u00f3n por la que estoy escribiendo este post es para recoger opiniones sobre si os parecen importantes o no, y si mi manera de resolverlos parece razonable para poder enviarlas como &#8220;feature requests&#8221;.<\/p>\n<h2>Mensajes de EXPLAIN<\/h2>\n<p>Como instructor MySQL, el caso siguiente me ocurre mucho con nuevos estudiantes. Comienza con un comando como el siguiente:<\/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>Entonces, &#8220;<code>Using index<\/code>&#8221; significa que se est\u00e1 usando un \u00edndice, \u00bfverdad? No, en este caso <code>type: index<\/code> nos indica que se est\u00e1 usando un \u00edndice para escanear o acceder a las filas (porque no es un <code>type: ALL<\/code>&#8211; aunque podr\u00edamos obtener un full row scan e usar el \u00edndice para ordenar o agruparlas). El <code>Extra: Using index<\/code> indica que el \u00edndice se usa para devolver los datos, sin necesidad de leer la fila completa. A esto, por lo que yo s\u00e9, se le refiere com\u00fanmente como <em>Covering index<\/em>. Y eso es exactamente lo que me gustar\u00eda ver:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT b, c FROM test\\G -- salida editada\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>o alternativamente:<\/p>\n<pre>        Extra: Covering index<\/pre>\n<p>Otro malentendido com\u00fan: <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>A este nivel no me interesa si estoy usando <em>filesort<\/em> como algoritmo y -si no me equivoco- desde 5.6 tambi\u00e9n se puede usar una cola de prioridad como algoritmo de ordenamiento si el numero de elementos es peque\u00f1o. Adem\u00e1s, el &#8220;file&#8221; de la palabra <em>filesort<\/em> puede llevar la confusi\u00f3n de que esto requiera una tabla temporal en disco. No tengo una alternativa perfecta (por favor, dadme ideas), pero algo como lo siguiente ser\u00eda m\u00e1s claro:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT * FROM test ORDER BY length(b)\\G  -- salida editada\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>o alternativamente:<\/p>\n<pre>        Extra: Not using index for order-by<\/pre>\n<p>Otro ejemplo ser\u00eda:<\/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>Entiendo que quiz\u00e1 los desarrolladores no quisieron confundirnos con la t\u00e9cnica <em>pushed condition<\/em> de  NDB, pero esta salida lleva al equ\u00edvoco tambi\u00e9n. Literalmente significa que &#8220;la condici\u00f3n del \u00edndice se est\u00e1 usando&#8221;, en vez de que se est\u00e1 usando &#8220;<a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.6\/en\/index-condition-pushdown-optimization.html\">ICP<\/a>. \u00bfQu\u00e9 os parece:<\/p>\n<pre>mysql&gt; EXPLAIN SELECT a FROM test WHERE b &gt; 3 and c = 3\\G -- salida editada\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>Hay <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.7\/en\/explain-output.html\">muchas otras expresiones<\/a>, pero esas son las que m\u00e1s me molestas en t\u00e9rminos de confusi\u00f3n de estudiantes.<\/p>\n<p>\u00bfEst\u00e1s de acuerdo conmigo? \u00bfRomper\u00edan estos cambios aplicaciones que parsean la salida de EXPLAIN? \u00bfQu\u00e9 otras peque\u00f1as cosas cambiar\u00edas en la salida de MySQL or sus mensajes de error? Me gustar\u00eda o\u00edr especialmente a los que est\u00e1n empezando con MySQL y a las personas que vengan de otras bases de datos, ya que cuanto m\u00e1s lo usamos, m\u00e1s nos acostumbramos a los MySQLismos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aunque siempre deseamos un mayor rendimiento y m\u00e1s y mejores caracter\u00edsticas para MySQL, estas no pueden aparecer &#8220;sin m\u00e1s&#8221; de una versi\u00f3n a otra, requiriendo profundos cambios en la arquitectura y muchas l\u00edneas de c\u00f3digo. Sin embargo, a veces hay<\/p>\n","protected":false},"author":1,"featured_media":693,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[85],"tags":[322,314,318,312,306,457,196,320,310,308,316,324],"class_list":["post-702","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mysql-es","tag-explain-es","tag-filesort","tag-icp","tag-index","tag-mensages","tag-mysql-es","tag-primary","tag-pushdown","tag-using-filesort","tag-using-index","tag-using-index-condition","tag-wishlist-es"],"_links":{"self":[{"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/702","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=702"}],"version-history":[{"count":3,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/702\/revisions"}],"predecessor-version":[{"id":1042,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/posts\/702\/revisions\/1042"}],"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=702"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/categories?post=702"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jynus.com\/dbahire\/wp-json\/wp\/v2\/tags?post=702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}