Aller au contenu

Performance requete...


Sujets conseillés

Posté

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 ;)

Posté

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,

Posté

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...

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...