|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Bonjour
J'essaie d'optimiser une requête SQL appelée un grand nombre de fois par un script : Code :
Pour le 'RADIANS (latitude)' répété 2 fois on ne peut pas écrire 'COS (RADIANS (latitude) AS L)' au milieu du calcul, faut-il le pré-déclarer dans le select même si la valeur n'est pas renvoyée ? 2- Le résultat est une chaine et non un nombre (la partie entière me suffit d'où le 'intval') 3- Si c'était un nombre je suppose que MIN pourrait être utilisé à la place de 'ORDER BY D ASC LIMIT 1' (marche pas) ? Enfin de façon générale faut-il partir du principe que SQL est plus rapide que php ?? Merci d'avance |
||
|
|
00
|
|
|
#2 |
|
Membre expérimenté
![]() Frédéric Inscription : juin 2011 Messages : 442 ![]() |
Je suppose qu'à chaque appel, il n'y a pas 50 villes qui ont le même nom. Le calcul n'étant pas fait un grand nombre de fois, son coût est probablement négligeable par rapport au coût de la requête.
De même pour le ORDER BY, vu qu'il n'y a pas grand chose à trier, ce n'est probablement pas la peine de s'y attarder. Reste le : Tu pourrais mettre "=" et as tu bien indexé VILLE ? |
|
|
00
|
|
|
#3 |
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
En fait c'est toute la fonction qui appelée un grand nombre de fois (elle est dans une boucle) ... avec des noms test $new différents.
Sinon, la probabilité de doublons ('VILLE') est effectivement très faible. A part ça le LIKE gère les accents. Les noms 'VILLE' sont directement codés en utf8 (Périgueux = Périgueux) mais je ne sais pas si c'est la meilleure solution. Je l'ai récupéré comme ça (chez geonames), et à vrai dire je n'ai pas encore géré le problème des accents de façon plus poussée. Et quant à l'indexation de la colonne j'avoue ne pas non plus avoir étudié le truc .. Je précise que la table n'est pas très volumineuse (38000 entrées) et qu'elle a une clé primaire. Elle sert également à une autocompletion. Si il y a un vrai bénéfice à indexer la colonne, j'indexe .. |
|
|
00
|
|
|
#4 |
|
Membre expérimenté
![]() Frédéric Inscription : juin 2011 Messages : 442 ![]() |
Il va te falloir 2 minutes pour ajouter un index, et 2 minutes pour l'enlever si les résultats ne sont pas concluants. Ça vaut le coup d'essayer...
Je peux comprendre l'utilité d'une telle fonction, mais je n'arrive pas à comprendre son intérêt lorsqu'elle est dans une boucle. |
|
|
00
|
|
|
#5 | |
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Ok, je regarderai l'indexation de plus près, également si ça m'aide à gérer les accents.
Citation:
|
|
|
|
00
|
|
|
#6 | ||
|
Membre expérimenté
![]() Frédéric Inscription : juin 2011 Messages : 442 ![]() |
Au lieu d'une boucle, tu pourrais faire une seule requête de ce genre :
Code :
|
||
|
|
10
|
|
|
#7 |
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Pourquoi pas, mais dans le parsing je fabrique un tableau de tableaux...
Alors ça m'obligerait à ajouter d'autres boucles : une pour extraire les noms des villes des tableaux, puis une autre pour insérer la distance dans le tableau de la ville correspondante (avec un test).. Je suis pas sûr que ça optimise. A propos de MIN c'était une de mes questions : la requête suivante ne renvoie rien .. Code :
SELECT MIN (6371 * ACOS (SIN (RADIANS (latitude)) * SIN(:lat) + COS (RADIANS (latitude)) * COS (:lat) * COS (RADIANS (longitude) - :lon))) FROM `fr` WHERE :ville LIKE VILLE |
|
|
00
|
|
|
#8 | |
|
Membre régulier
![]() Inscription : février 2013 Messages : 47 ![]() |
Citation:
|
|
|
|
00
|
|
|
#9 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Désolé, en fait le MIN marche très bien (avec LIKE dans les 2 sens) et permet de remplacer le 'ORDER BY D ASC LIMIT 1'.
Version simplifiée : Code :
J'ai fait la structure la plus évidente avec cette fonction appelée dans la boucle principale, comme si c'était une fonction de calcul normale. Dans la mesure où c'est une requête SQL ce n'est peut-être pas le bon raisonnement, je ne sais pas .. |
||
|
|
00
|
|
|
#10 |
|
Expert Confirmé
![]() Eric DureuilDéveloppeur informatique Inscription : avril 2011 Messages : 1 804 ![]() |
salut,
et si tu utilisais une fonction stockée pour la formule, ça te permettrait au moins de simplifier l'écriture de ce genre de requête, de limiter la taille de code à transférer à mysql et si tu appelles la fonction plusieurs fois dans la même session tu as en plus le gain de la compilation et du plan d'exécution...
__________________
soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...
|
|
|
00
|
|
|
#11 |
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Salut
J'ai jeté un œil aux procédures stockées .. effectivement c'est pas bête (c'est un peu comme définir une méthode) et probablement plus rapide. Si je reste sur cette structure je l'adopte. En gros j'ai le choix entre : - cette structure qui répète la requête SQL (mettons de 10 à 300 fois par requête, en procédure stockée) - une structure php plus compliquée qui fait 1 seule requête SQL (plus compliquée aussi) Je ne sais pas si la 1ère solution (plus simple) est un handicap pour un serveur normal, si quelqu'un sait surtout qu'il n'hésite pas .. Et sinon merci pour vos réponses. |
|
|
00
|
|
|
#12 |
|
Membre expérimenté
![]() Frédéric Inscription : juin 2011 Messages : 442 ![]() |
300 requêtes c'est souvent plus handicapant qu'une seule requête...
As-tu ajouté un index ? |
|
|
00
|
|
|
#13 |
|
Expert Confirmé
![]() Eric DureuilDéveloppeur informatique Inscription : avril 2011 Messages : 1 804 ![]() |
c'est surtout un gain dans l'écriture si ce calcul entre dans plusieurs requête...
de toutes façons, je recommande toujours de séparer langage appelant du sql en utilisant du procédural... ça renforce encore la sécurité et l'isolation et la maintenance... en général, pour les problème de distance à des coordonnées (ou une autre ville de référence) tu fais ton calcul de distance par rapport à chaque ville que tu classes en ordre desc sur la distance avec un "limit 1" et tu as ton résultat... pas besoin de traitement externe à mysql...
__________________
soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...
|
|
|
00
|
|
|
#14 | ||
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Citation:
Citation:
J’essaierai en procédure stockée, ça m'a l'air effectivement plus pertinent (également pour l'autocompletion d'ailleurs). Pour ce qui est de la structure je ne chasse pas les millisecondes, c'est juste histoire de ne pas partir sur un truc foireux .. |
||
|
|
00
|
|
|
#15 |
|
Expert Confirmé
![]() Eric DureuilDéveloppeur informatique Inscription : avril 2011 Messages : 1 804 ![]() |
je voulais te faire comprendre que c'est le genre de traitement (boucle ou autre truc) que tu n'as pas forcément à faire coté langage appelant...
une fois tes données chargées en bd tu peux faire plein de choses en procédural en bd et éviter les allers-retours avec le langage appelant
__________________
soyons pensez à mettre quand votre problème est résolu ou à utiliser pour les réponses pertinentes...ne posez pas de problématique soi-disant simplifiée sur des problèmes que vous n'êtes pas capable de résoudre par respect pour ceux qui planchent dessus... sinon: et à utiliser pour insérer votre code...
|
|
|
00
|
|
|
#16 | |||
|
Candidat au titre de Membre du Club
![]() Inscription : juin 2008 Messages : 54 ![]() |
Citation:
Alors j'ai fait un essai avec le code de Fred (message #6) écrit sur mesure, il gère les éventuels doublons de nom de villes en renvoyant la plus proche .. il marche impeccable ! Ça m'oblige à réécrire mes parsings pour extraire les noms des villes dans un tableau à part, puis à les refusionner .. mais c'est sans doute une meilleure solution. Ça donnerait quelque chose comme ça : Code :
Code :
$new = array ('Paris', 'Lyon', 'Marseille') Bref, merci de m'avoir fait comprendre... |
|||
|
|
00
|
Copyright © 2000-2013 - www.developpez.com