
{"id":1370,"date":"2013-01-30T10:55:52","date_gmt":"2013-01-30T09:55:52","guid":{"rendered":"http:\/\/dasini.net\/blog\/?p=1370"},"modified":"2013-01-30T10:55:52","modified_gmt":"2013-01-30T09:55:52","slug":"full-table-scan-vs-full-index-scan-part2-2","status":"publish","type":"post","link":"https:\/\/dasini.net\/blog\/2013\/01\/30\/full-table-scan-vs-full-index-scan-part2-2\/","title":{"rendered":"Full table scan vs Full index scan part2-2"},"content":{"rendered":"<h1 dir=\"ltr\">2\/ FTS ou FIS<\/h1>\n<p><em>(<a title=\"1\/ Le myst\u00e8re de la variable Last_query_cost\" href=\"https:\/\/dasini.net\/blog\/2013\/01\/08\/full-table-scan-vs-full-index-scan-part1-2\/\">Aller \u00e0 la 1\u00e8re partie<\/a>)<\/em><br \/>\nAvant de r\u00e9pondre explicitement \u00e0 la question, un petit zoom sur l\u2019une des nombreuses nouveaut\u00e9s de MySQL 5.6. La commande <strong>EXPLAIN<\/strong> s\u2019est enrichie de la clause <strong>format=json<\/strong>. Elle permet d\u2019avoir une version un peu plus d\u00e9taill\u00e9e que l\u2019EXPLAIN classique.<\/p>\n<p>Query 1\/ EXPLAIN <strong>format=json<\/strong> \u00a0SELECT d,avg(price) FROM bills GROUP BY d\\G<br \/>\n*************************** 1. row ***************************<br \/>\nEXPLAIN: {<br \/>\n\u00ab\u00a0query_block\u00a0\u00bb: {<br \/>\n\u00ab\u00a0select_id\u00a0\u00bb: 1,<br \/>\n\u00ab\u00a0grouping_operation\u00a0\u00bb: {<br \/>\n\u00ab\u00a0using_filesort\u00a0\u00bb: false,<br \/>\n\u00ab\u00a0table\u00a0\u00bb: {<br \/>\n\u00ab\u00a0table_name\u00a0\u00bb: \u00ab\u00a0bills\u00a0\u00bb,<br \/>\n\u00ab\u00a0access_type\u00a0\u00bb: \u00ab\u00a0index\u00a0\u00bb,<br \/>\n\u00ab\u00a0key\u00a0\u00bb: \u00ab\u00a0d\u00a0\u00bb,<br \/>\n\u00ab\u00a0used_key_parts\u00a0\u00bb: [<br \/>\n\u00ab\u00a0d\u00a0\u00bb<br \/>\n],<br \/>\n\u00ab\u00a0key_length\u00a0\u00bb: \u00ab\u00a05\u00a0\u00bb,<br \/>\n\u00ab\u00a0rows\u00a0\u00bb: 176268,<br \/>\n\u00ab\u00a0filtered\u00a0\u00bb: 100<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>Query 4\/ EXPLAIN <strong>format=json<\/strong> \u00a0SELECT d,avg(price) FROM bills IGNORE INDEX(d) GROUP BY d\\G<br \/>\n*************************** 1. row ***************************<br \/>\nEXPLAIN: {<br \/>\n\u00ab\u00a0query_block\u00a0\u00bb: {<br \/>\n\u00ab\u00a0select_id\u00a0\u00bb: 1,<br \/>\n\u00ab\u00a0grouping_operation\u00a0\u00bb: {<br \/>\n\u00ab\u00a0using_temporary_table\u00a0\u00bb: true,<br \/>\n\u00ab\u00a0using_filesort\u00a0\u00bb: true,<br \/>\n\u00ab\u00a0table\u00a0\u00bb: {<br \/>\n\u00ab\u00a0table_name\u00a0\u00bb: \u00ab\u00a0bills\u00a0\u00bb,<br \/>\n\u00ab\u00a0access_type\u00a0\u00bb: \u00ab\u00a0ALL\u00a0\u00bb,<br \/>\n\u00ab\u00a0rows\u00a0\u00bb: 176268,<br \/>\n\u00ab\u00a0filtered\u00a0\u00bb: 100<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>Sans surprise, on retrouve les informations de la version classique de l\u2019EXPLAIN, a savoir:<br \/>\nFIS d\u2019un cot\u00e9 (choix de l\u2019optimiseur) contre FTS + cr\u00e9ation d\u2019une table temporaire + tri de l\u2019autre. N\u00e9anmoins, pour certains types de requ\u00eates, les informations g\u00e9n\u00e9r\u00e9es par la clause format=json peuvent \u00eatre plus pertinentes.<\/p>\n<p>Comme nous l\u2019avons \u00e9galement vu dans <a href=\"http:\/\/dasini.net\/blog\/2013\/01\/08\/full-table-scan-vs-full-index-scan-part1-2\/\">la premi\u00e8re partie de cet article<\/a>, le GROUP BY de MySQL g\u00e9n\u00e8re syst\u00e9matiquement un tri (\u00ab\u00a0using_filesort\u00a0\u00bb: true,). Ce tri n\u2019\u00e9tant pas toujours n\u00e9cessaire, il y a une astuce pour ne pas le g\u00e9n\u00e9rer. Ajouter la clause <strong>ORDER BY NULL<\/strong><\/p>\n<p>Query 5\/ EXPLAIN format=json \u00a0SELECT d,avg(price) FROM bills IGNORE INDEX(d) GROUP BY d <strong>ORDER BY NULL<\/strong>\\G<br \/>\n*************************** 1. row ***************************<br \/>\nEXPLAIN: {<br \/>\n\u00ab\u00a0query_block\u00a0\u00bb: {<br \/>\n\u00ab\u00a0select_id\u00a0\u00bb: 1,<br \/>\n\u00ab\u00a0ordering_operation\u00a0\u00bb: {<br \/>\n<strong> \u00a0\u00a0\u00a0\u00a0 \u00ab\u00a0using_filesort\u00a0\u00bb: false,<\/strong><br \/>\n\u00ab\u00a0grouping_operation\u00a0\u00bb: {<br \/>\n<strong> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00ab\u00a0using_temporary_table\u00a0\u00bb: true,<\/strong><br \/>\n<strong> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00ab\u00a0using_filesort\u00a0\u00bb: false,<\/strong><br \/>\n\u00ab\u00a0table\u00a0\u00bb: {<br \/>\n\u00ab\u00a0table_name\u00a0\u00bb: \u00ab\u00a0bills\u00a0\u00bb,<br \/>\n\u00ab\u00a0access_type\u00a0\u00bb: \u00ab\u00a0ALL\u00a0\u00bb,<br \/>\n\u00ab\u00a0rows\u00a0\u00bb: 176268,<br \/>\n\u00ab\u00a0filtered\u00a0\u00bb: 100<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>Query 5\/ EXPLAIN \u00a0SELECT d,avg(price) FROM bills IGNORE INDEX(d) GROUP BY d <strong>ORDER BY NULL<\/strong>\\G<br \/>\n*************************** 1. row ***************************<br \/>\nid: 1<br \/>\nselect_type: SIMPLE<br \/>\ntable: bills<br \/>\ntype: ALL<br \/>\npossible_keys: NULL<br \/>\nkey: NULL<br \/>\nkey_len: NULL<br \/>\nref: NULL<br \/>\nrows: 176268<br \/>\n<strong> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Extra: Using temporary<\/strong><\/p>\n<p>SHOW STATUS LIKE &lsquo;Last_query_cost&rsquo;;<br \/>\n+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+<br \/>\n| Variable_name \u00a0\u00a0| Value \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 |<br \/>\n+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+<br \/>\n| Last_query_cost | 35861.599000 |<br \/>\n+&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8211;+<\/p>\n<p>Il y a une incidence notable sur le co\u00fbt de la requ\u00eate, <strong>35861.599<\/strong> au lieu de <strong>212129.599<\/strong>.<br \/>\nPas vraiment surprenant !<\/p>\n<p>Niveau performance \u00e7a donne quoi ?<\/p>\n<h3 dir=\"ltr\">Quick bench (au meilleur des 4 tests ie 4 fois 100 runs):<\/h3>\n<p>Server version: \u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0<strong>5.6.9<\/strong>-rc MySQL Community Server (GPL)<\/p>\n<p>Taille: environs <strong>16 Mo<\/strong> ((Donn\u00e9es + Index))<\/p>\n<p>Configuration de l\u2019instance:<br \/>\nInnodb buffer pool size = <strong>32 Go<\/strong><br \/>\nmax_heap_table_size = tmp_table_size = <strong>512 Mo<\/strong><\/p>\n<p>Query 1:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills \u00a0GROUP BY d ;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.203 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.199 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.224 seconds<\/p>\n<p>Query 2:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills USE INDEX(d) GROUP BY d ;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.206 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.198 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.217 seconds<\/p>\n<p>Query 3:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills FORCE INDEX(d) GROUP BY d ;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.203 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.199 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.219 seconds<\/p>\n<p>Le temps d\u2019ex\u00e9cution des requ\u00eates 1, 2 et 3 est le m\u00eame ce qui est logique car le plan d\u2019ex\u00e9cution est le m\u00eame, en d\u2019autres termes, forcer l\u2019utilisation de l\u2019index ou non n\u2019a pas d\u2019incidence sur la dur\u00e9e des requ\u00eates.<br \/>\nDe plus ce r\u00e9sultat confirme que le co\u00fbt bizarre du FORCE INDEX est bien un bug (cf <a href=\"http:\/\/dasini.net\/blog\/2013\/01\/08\/full-table-scan-vs-full-index-scan-part1-2\/\">la premi\u00e8re partie de cet article<\/a>).<\/p>\n<p>Query 4:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills IGNORE INDEX(d) GROUP BY d ;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.168 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.166 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.172 seconds<\/p>\n<p>Plusieurs indications:<\/p>\n<ul>\n<li dir=\"ltr\">Le full table scan donne un meilleur temps d\u2019ex\u00e9cution que le full index scan:\n<ul>\n<li dir=\"ltr\">0.166 vs 0.199<\/li>\n<li dir=\"ltr\">D\u2019une mani\u00e8re g\u00e9n\u00e9rale, le FTS et plus rapide que le FIS sauf dans le cas d\u2019un index covering (using index)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li dir=\"ltr\">Le co\u00fbt de la cr\u00e9ation de la table temporaire et du tri n\u2019a pas un impact suffisant pour que le temps d\u2019ex\u00e9cution soit sup\u00e9rieur au FIS:\n<ul>\n<li dir=\"ltr\">Created_tmp_tables: 1, Created_tmp_disk_tables: 0, \u00a0Sort_merge_passes: 0<\/li>\n<li dir=\"ltr\">Seules 231 lignes sont \u00e0 trier (Handler_read_rnd = 231)<\/li>\n<li dir=\"ltr\">Ces op\u00e9rations se d\u00e9roulent en m\u00e9moire (ie pas d\u2019acc\u00e8s disque). C\u2019est essentiellement un co\u00fbt processeur.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Et avec l\u2019astuce ORDER BY NULL ?<\/p>\n<p>Query 6:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills <strong>USE INDEX(d)<\/strong> GROUP BY d ORDER BY NULL;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.203 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.199 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.218 seconds<\/p>\n<p>Pas de tri, pas d\u2019incidence sur les perfs, trivial<\/p>\n<p>Query 5:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills <strong>IGNORE INDEX(d) GROUP BY d ORDER BY NULL<\/strong>;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.168 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.166 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.172 seconds<\/p>\n<p>Le co\u00fbt du tri est faible, n\u00e9gligeable =&gt; pas d\u2019incidences sur les perfs<\/p>\n<h3 dir=\"ltr\">En diminuant la taille des param\u00e8tres max_heap_table_size &amp; tmp_table_size :<\/h3>\n<p>Taille: environs <strong>16 Mo<\/strong> ((Donn\u00e9es + Index))<\/p>\n<p>Configuration de l\u2019instance:<br \/>\nInnodb buffer pool size = <strong>32 Go<\/strong><br \/>\n<span style=\"color: #ff0000;\">max_heap_table_size = tmp_table_size = <strong>16 Ko<\/strong><\/span><\/p>\n<p><a href=\"http:\/\/dasini.net\/blog\/2010\/05\/28\/audit-mysql-tmp_table_size-max_heap_table_size\/\">Infos sur les variables tmp_table_size &amp; max_heap_table_size<\/a><\/p>\n<p>En diminuant max_heap_table_size &amp; tmp_table_size, pour forcer la cr\u00e9ation de la table temporaire sur le disque:<\/p>\n<p>Query 2:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills USE INDEX(d) GROUP BY d;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.203 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.199 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.221 seconds<\/p>\n<p>Pas d\u2019incidence sur les perfs, car pas de tri donc pas de cr\u00e9ations de table temporaire. Trivial !<\/p>\n<p>Query 4:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills IGNORE INDEX(d) GROUP BY d;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.767 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: <span style=\"color: #ff0000;\">0.757<\/span> seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.778 seconds<\/p>\n<p>Sans surprise, c\u2019est plus long. La table temporaire \u00e9tant cr\u00e9\u00e9e sur disque.<\/p>\n<p>Query 5:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills IGNORE INDEX(d) GROUP BY d ORDER BY NULL;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.765 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries:<span style=\"color: #ff0000;\"> 0.756<\/span> seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.773 seconds<\/p>\n<p>Le tri \u00e9tant fait en m\u00e9moire, les variables max_heap_table_size &amp; tmp_table_size n\u2019ont pas d\u2019incidences sur le tri.<\/p>\n<h3 dir=\"ltr\">En diminuant la taille du param\u00e8tre innodb_buffer_pool_size :<\/h3>\n<p>Taille: environs <strong>16 Mo<\/strong> ((Donn\u00e9es + Index))<\/p>\n<p>Configuration de l\u2019instance:<br \/>\n<span style=\"color: #ff0000;\">Innodb buffer pool size =<strong> 8 Mo<\/strong><\/span><br \/>\nmax_heap_table_size = tmp_table_size = <strong>512 Mo<\/strong><\/p>\n<p>Query 2:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills USE INDEX(d) GROUP BY d ;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 1.214 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: <span style=\"color: #ff0000;\">1.174<\/span> seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 1.243 seconds<\/p>\n<p>Query 4:<br \/>\ndaz@mysql:~\/mysql_5_6_5$ .\/mysqlslap &#8211;create-schema=test -c1 -i100 -q\u00a0\u00bbSELECT avg(price) FROM test.bills IGNORE INDEX(d) GROUP BY d ;\u00a0\u00bb<br \/>\nBenchmark<br \/>\nAverage number of seconds to run all queries: 0.179 seconds<br \/>\n<strong> \u00a0\u00a0\u00a0Minimum number of seconds to run all queries: 0.174 seconds<\/strong><br \/>\nMaximum number of seconds to run all queries: 0.185 seconds<\/p>\n<p>L\u2019\u00e9cart de performance est encore plus important avec des donn\u00e9es qui ne tiennent (apparemment) pas enti\u00e8rement en m\u00e9moire. Le sur-co\u00fbt I\/O impos\u00e9 par la double recherche (dans l\u2019index secondaire, puis random I\/O dans la cl\u00e9 primaire) n\u2019est pas anodin.<\/p>\n<p><span style=\"text-decoration: underline;\">Conclusion<\/span><br \/>\n&#8211; Le choix de l\u2019optimiseur n\u2019est parfois pas le bon<br \/>\n&#8211; Le choix le plus intuitif n\u2019est parfois pas le plus performant<br \/>\n&#8211; Toujours valider ses hypoth\u00e8ses par la pratique<br \/>\n&#8211; Se m\u00e9fier des Full Index Scan, qui peuvent \u00eatre vraiment plus co\u00fbteux qu\u2019un Full Table Scan en cas de non covering index<\/p>\n","protected":false},"excerpt":{"rendered":"<p>2\/ FTS ou FIS<\/p>\n<p>Avant de r\u00e9pondre explicitement \u00e0 la question, un petit zoom sur l\u2019une des nombreuses nouveaut\u00e9s de MySQL 5.6. La commande EXPLAIN s\u2019est enrichie de la clause format=json. Elle permet d\u2019avoir une version un peu plus d\u00e9taill\u00e9e que l\u2019EXPLAIN classique.<\/p>\n<p>Query 1\/ EXPLAIN format=json  SELECT d,avg(price) FROM bills GROUP BY d\\G<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[34],"tags":[],"class_list":["post-1370","post","type-post","status-publish","format-standard","hentry","category-optimisation"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9LfWW-m6","jetpack-related-posts":[{"id":1363,"url":"https:\/\/dasini.net\/blog\/2013\/01\/08\/full-table-scan-vs-full-index-scan-part1-2\/","url_meta":{"origin":1370,"position":0},"title":"Full table scan vs Full index scan part1-2","author":"Olivier DASINI","date":"8 janvier 2013","format":false,"excerpt":"MySQL utilise un optimiseur \u00e0 base de co\u00fbts. Le plan d\u2019ex\u00e9cution de la requ\u00eate choisit est celui dont le co\u00fbt est le plus faible. Ce dernier peut \u00eatre visualis\u00e9 gr\u00e2ce \u00e0 la variable Last_query_cost. Son unit\u00e9 est le co\u00fbt (encore lui) des acc\u00e8s al\u00e9atoires en lecture de pages de 4ko.\u2026","rel":"","context":"Dans &quot;optimisation&quot;","block_context":{"text":"optimisation","link":"https:\/\/dasini.net\/blog\/category\/optimisation\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":453,"url":"https:\/\/dasini.net\/blog\/2009\/02\/18\/optimisation-de-requetes-comprendre-loptimiseur-de-mysql\/","url_meta":{"origin":1370,"position":1},"title":"Optimisation de requ\u00eates: comprendre l&rsquo;optimiseur de MySQL","author":"Olivier DASINI","date":"18 f\u00e9vrier 2009","format":false,"excerpt":"Le but de cet article est d'optimiser une simple requ\u00eate (SELECT avg(Population) FROM city GROUP BY CountryCode) et surtout de comprendre comment l'optimiseur proc\u00e8de, en \u00e9tudiant les r\u00e9sultats donn\u00e9s par les variables qui permettent de surveiller le serveur MySQL.","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":430,"url":"https:\/\/dasini.net\/blog\/2009\/01\/29\/influencer-loptimiseur-de-mysql\/","url_meta":{"origin":1370,"position":2},"title":"Influencer l&rsquo;optimiseur de MySQL","author":"Olivier DASINI","date":"29 janvier 2009","format":false,"excerpt":"Il est possible d'influencer l'optimiseur pour qu'il choisisse d'utiliser ou de ne pas utiliser un index particulier. Les clauses \u00e0 placer dans votre requ\u00eate SELECT sont les suivantes: USE INDEX : utilise l'index pass\u00e9 en argument (MySQL ne l'utilisera pas si l'index est plus couteux qu'un full table scan) FORCE\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1533,"url":"https:\/\/dasini.net\/blog\/2015\/11\/17\/30-mins-avec-json-en-mysql\/","url_meta":{"origin":1370,"position":3},"title":"30 mins avec JSON en MySQL","author":"Olivier DASINI","date":"17 novembre 2015","format":false,"excerpt":"Comme vous le savez MySQL 5.7 est GA. Cette nouvelle mouture de la base de donn\u00e9es open source la plus populaire au monde a plus de 150 nouvelles fonctionnalit\u00e9s. L'une d'entre elle est un type de donn\u00e9es JSON natif ainsi que les fonctions JSON associ\u00e9es. Prenons 30 minutes pour voir\u2026","rel":"","context":"Dans &quot;json&quot;","block_context":{"text":"json","link":"https:\/\/dasini.net\/blog\/category\/json-fr\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1557,"url":"https:\/\/dasini.net\/blog\/2015\/11\/30\/json-et-colonnes-generees-avec-mysql\/","url_meta":{"origin":1370,"position":4},"title":"JSON et colonnes g\u00e9n\u00e9r\u00e9es avec MySQL","author":"Olivier DASINI","date":"30 novembre 2015","format":false,"excerpt":"Le 24 novembre dernier, lors du Forum PHP, Tomas Ulin (Oracle's MySQL VP of Engineering) a parl\u00e9 de l'utilisation de JSON dans MySQL \"MySQL 5.7 & JSON: New opportunities for developers\". Voici les r\u00e9ponses \u00e0 quelques questions qui m'ont \u00e9t\u00e9 pos\u00e9es: Comment se comporte mysqldump avec les colonnes g\u00e9n\u00e9r\u00e9es ?\u2026","rel":"","context":"Dans &quot;json&quot;","block_context":{"text":"json","link":"https:\/\/dasini.net\/blog\/category\/json-fr\/"},"img":{"alt_text":"JSON","src":"https:\/\/i0.wp.com\/dasini.net\/blog\/wp-content\/uploads\/json_icon.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1163,"url":"https:\/\/dasini.net\/blog\/2012\/01\/09\/ameliorations-de-loptimiseur-dans-mariadb\/","url_meta":{"origin":1370,"position":5},"title":"Am\u00e9liorations de l&rsquo;optimiseur dans MariaDB","author":"Olivier DASINI","date":"9 janvier 2012","format":false,"excerpt":"Les \u00e9quipes de MariaDB ont \u00e9norm\u00e9ment travaill\u00e9es sur l'optimiseur de la version 5.3, notamment en permettant une r\u00e9elle utilisation des sous-requ\u00eates. Voici un effet visuel de ces optimisations: Avec MySQL 5.5, l'utilisation de tables d\u00e9riv\u00e9es (type de sous-requ\u00eates dans la clause FROM d'un SELECT), donne le plan d'ex\u00e9cution suivant:","rel":"","context":"Dans &quot;bench&quot;","block_context":{"text":"bench","link":"https:\/\/dasini.net\/blog\/category\/bench\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/1370","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/comments?post=1370"}],"version-history":[{"count":2,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/1370\/revisions"}],"predecessor-version":[{"id":1372,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/1370\/revisions\/1372"}],"wp:attachment":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/media?parent=1370"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/categories?post=1370"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/tags?post=1370"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}