{"id":161,"date":"2005-08-17T13:53:37","date_gmt":"2005-08-17T13:53:37","guid":{"rendered":"http:\/\/www.lucas-nussbaum.net\/blog\/?p=161"},"modified":"2005-08-17T13:53:37","modified_gmt":"2005-08-17T13:53:37","slug":"comment-se-faire-hair-de-son-hebergeur-en-quelques-minutes","status":"publish","type":"post","link":"https:\/\/www.lucas-nussbaum.net\/blog\/?p=161","title":{"rendered":"Comment se faire ha\u00efr de son h\u00e9bergeur en quelques minutes"},"content":{"rendered":"<p><u>Disclaimer :<\/u> toute ressemblance avec le code d&#8217;un site existant permettant d&#8217;\u00e9changer des maisons est totalement fortuite.<\/p>\n<p>Il est tr\u00e8s facile d&#8217;abuser de MySQL pour le transformer en une arme de destruction massive pour les performances de votre h\u00e9bergeur. Il y a deux mani\u00e8res tr\u00e8s simples d&#8217;y arriver :<\/p>\n<ul>\n<li>Transf\u00e9rer le plus souvent possible d&#8217;\u00e9normes quantit\u00e9s de donn\u00e9es du serveur SQL au serveur web. Bien s\u00fbr, votre script n&#8217;a pas besoin de toutes ces donn\u00e9es, mais utiliser un SELECT restreint au lieu d&#8217;un SELECT *, ou pire, utiliser LIMIT, c&#8217;est tellement compliqu\u00e9 &#8230; alors que c&#8217;est si simple \u00e0 faire en PHP. Par exemple, dans de vieilles versions de SPIP, la fonction charg\u00e9e de nettoyer le cache (stock\u00e9 dans MySQL) transf\u00e9rait l&#8217;ensemble du cache avant de d\u00e9cider si chaque entr\u00e9e devait \u00eatre conserv\u00e9e ou non. (C&#8217;est corrig\u00e9 depuis f\u00e9vrier 2005 d&#8217;apr\u00e8s le CVS de SPIP)<\/li>\n<li>Une autre mani\u00e8re plus pernicieuse est de g\u00e9n\u00e9rer dynamiquement des requ\u00eates SQL sans se poser la question des cas extr\u00e8mes de requ\u00eates g\u00e9n\u00e9r\u00e9es. Prenons un petit exemple.<\/li>\n<\/ul>\n<p>Cr\u00e9ons une petite table :<\/p>\n<pre>CREATE TABLE `torture` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT , `value` INT, PRIMARY KEY ( `id` ) ) TYPE = MYISAM ;<\/pre>\n<p>\u00c0 l&#8217;aide d&#8217;un petit script PHP, remplissons l\u00e0 avec 10000 valeurs, ce qui n&#8217;est pas si \u00e9norme que \u00e7a.<\/p>\n<pre>for ($i = 0; $i  <p>Maintenant, la partie int\u00e9ressante : g\u00e9n\u00e9rons dynamiquement une requ\u00eate.<\/p> <pre> $sql = \"SELECT id FROM torture WHERE TRUE\"; for ($i = 0; $i  \".rand(0, 10000); }<\/pre>\n<p>Vous l'aurez compris, pour <i>n = 10<\/i>, \u00e7a donne qqchose comme <i>SELECT id FROM torture WHERE TRUE AND value &lt;&gt; 14647 AND value &lt;&gt; 9936 AND value &lt;&gt; 10106 AND value &lt;&gt; 8136 AND value &lt;&gt; 5952 AND value &lt;&gt; 6908 AND value &lt;&gt; 14290 AND value &lt;&gt; 15359 AND value &lt;&gt; 2179 AND value &lt;&gt; 8005<\/i>.<\/p>\n<p>En se d\u00e9brouillant pour passer le param\u00e8tre <i>n<\/i> \u00e0 la page, on peut facilement tester pour diff\u00e9rentes valeurs de <i>n<\/i>. J'ai test\u00e9 sur le nouveau serveur MySQL d'<a href=\"http:\/\/www.apinc.org\/\">Apinc<\/a>, peu charg\u00e9 et tr\u00e8s performant. Si avec n = 10, la requ\u00eate ne met que 0.03s \u00e0 s'ex\u00e9cuter, elle met 2.8s avec n = 1000, et 22s (aye) avec n = 5000. Avec n = 10000, on atteint 38s.<\/p>\n<p>Histoire d'\u00eatre complet, on peut pr\u00e9ciser qu'ajouter un index sur la colonne <i>value<\/i> ne change rien : on n'\u00e9vite pas l'\u00e9valuation pour chaque ligne de la table. Par contre, en exprimant la m\u00eame requ\u00eate sous la forme <i>SELECT id FROM torture WHERE  value NOT IN(2791, 962, 49, 5845, 4425, 4129, 9905, 6468, 9681, 5776)<\/i>, on la transforme en une requ\u00eate s'ex\u00e9cutant imm\u00e9diatement (0.05s avec n = 10000)<\/p>\n<p>Conclusions :<\/p>\n<ul>\n<li><i>IN<\/i> et <i>NOT IN<\/i>, c'est bien(tm).<\/li>\n<li>Les requ\u00eates g\u00e9n\u00e9r\u00e9es dynamiquement sans connaitre leurs tailles, c'est mal(tm).<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer : toute ressemblance avec le code d&#8217;un site existant permettant d&#8217;\u00e9changer des maisons est totalement fortuite. Il est tr\u00e8s facile d&#8217;abuser de MySQL pour le transformer en une arme de destruction massive pour les performances de votre h\u00e9bergeur. Il y a deux mani\u00e8res tr\u00e8s simples d&#8217;y arriver : Transf\u00e9rer le plus souvent possible d&#8217;\u00e9normes [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"0","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-161","post","type-post","status-publish","format-standard","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=161"}],"version-history":[{"count":0,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/161\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}