lorik Posté 15 Février 2017 Posté 15 Février 2017 Bonjour à tous, Je suis assez surpris par les perfomances comparées de requetes assez simples : SELECT * FROM table1 WHERE cp IN (select toto from villes where code_postal=38000) => la requete tourne pendant presque 4 secondes. Pourtant : select toto from villes where code_postal=38000 ne met que 1 milisecondes. Et que si on met 'en dur, les valeurs à tester (le resultat du select toto from ville...) , on est aussi de l'ordre de la miliseconde.... SELECT * FROM table1 WHERE cp IN (38000,38950,38170,38100,38400,38180,38113,38220,38760,38340,38660,38450,38112,38134,38430,38960,38144,38119,38520,38770,73360,73670,73160,38620,38750,38830,38480,73520,73610,38840,38940,73800,73330,73110,73190,73530,73000,73240,73470,73130,73300,73490,73290,73230,73170,73660,73420,73390,73250,73370,73220,38890,73870,73340,73100,73450,73140,73630,73460,73310,73410,73440,73260,38070,74540,73600,73200,73550,73500,38138,74320,73730,74150,38118,73570,73350,74410,73540,69780,74210,69124,69720,69560,69125,38370,69970,74600,69420,73210,42520,73790,69330,73400,42410,74650) Bref, on passe de 2 milisecondes à ... 2000 fois plus !! Ya un truc qui m'échappe, là. Ca méchappe mais ça me pose un vrai souci, du coup, vos lumières sont les bienvenues
Aenoa Posté 15 Février 2017 Posté 15 Février 2017 Bonjour, la première effectue un SELECT * (toutes les colonnes) (que je déconseille, il vaut mieux spécifier les colonnes requises uniquement) et un IN (), qui doit donc parcourir toutes les données se trouvant dans la requête imbriquée, pour ensuite filtrer la requête primaire avec les données de l'imbriquée, et ce traitement prends du temps. La seconde ne possède pas de traitement, juste des valeurs brutes, ce qui réduit également le temps de traitement. Il doit simplement comparer une valeur avec une autre valeur, et non pas faire une récupération de valeur pour chaque enregistrement. Mon premier conseil serait avant-tout de changer votre SELECT * par le nom des colonnes requises, et si possible de faire une entrée de valeurs en brut. Ensuite, êtes-vous sûr que la colonne `villes`.`toto` contient une valeur de même type et identique à un enregistrement ? Aucun transtypage ne doit être fait par le serveur SQL ? Dans votre exemple, les données dans le IN devraient être toutes 38000 si l'on respecte la logique des noms, étant donné que votre requête récupère toutes les `toto` ayant comme `code_postal`= 38000, pour ensuite comparer la valeur de `toto` à `table1`.`cp` qui, d'après son nom, est aussi un code postal ? Cordialement,
lorik Posté 15 Février 2017 Auteur Posté 15 Février 2017 Merci de la réponse, Oui, je suis d'accord pour le *, mais le propos était surtout de comparer, l'optimisation ne réduit pas le gap entre les 2 méthodes. Pour le transtypage, non, rien de particulier, on a des listes de codes postaux bien formatés et homogènes... A la place de la sous requete, je pourrais aussi faire un INNER JOIN avec une autre table, mais elle fait 5 000 000 d'enregistrements, j'ai pensé que ça serait plus rapide comme ça...
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant