Requête PHP lourde

WRInaute passionné
Bonjour

J'ai un problème de requête PHP trop lourde.

C'est dans le but d'ajouter le nombre de connectés (guests et members) sur mon site en -www

Donc en fait le truc est fait :)
Pour afficher le module "nombre de connectés" sur toutes les pages du site, ce n'est pas du temps réel, mais un script exécuté toutes les deux minutes via cron job, infos stockées simplement dans un petits fichier PHP, donc un truc rapide, basé sur les utilisateurs connecté les 5 dernière minutes.

Donc ça c'est très bien.

Mais j'ai aussi une page "Online users"
http://www.twip.org/online-users.php
Ca c'est du temps réel, il va juste chercher rapidement dans la base de données les utilisateurs en ligne, il y en a 100 à 200 en moyenne sur 5 minutes, et il affiche les IP.

Ca c'est très bien aussi.

Mais je à chaque fois que j'affiche une IP, je voudrais afficher le pays auquel il correspond.
Donc j'ai récupéré une base de données de correspondance (environ 100.000 lignes), donc une grosse base !

Donc, pour chaque IP (environ 100 à 200)
Je converti l'IP en décimale avec la formule

Code:
$ipnum = 16777216*w + 65536*x + 256*y + z 

où

IP Address = w.x.y.z

Avec un simple explode () etc...

Une fois que j'ai le décimale, je fais un

Code:
SELECT ip_country FROM geoip WHERE $ipnum >= begin_ip_num AND $ipnum <= end_ip_num LIMIT 1

Et j'ai le pays

Ainsi j'ai UNE BOUCLE FOR pour les 200 IP environ (petite table donc très rapide)
Et uune BOUCLE FOR imbriquée pour à chaque fois la convertion IP -> décimale ET le requête MySQL dans une TRES GROSSE TABLE
Et la ra rame.

Donc ça marche mais ça rame, (peut être 20 seconde avant de s'afficher !)

Ma question est comment font les autres :)
Y a t-il quelque chose de plus simple ? un autre moyen ?

Merci et désolé pour le mal de crane de bon matin.
 
WRInaute passionné
Hello

en fait, je pense que c'est très simple : Tu n'affiches PAS le nombre de personnes connectées.
C'est complétement passé de mode.

OUT OF FASHION !

C'était du Web 1.0 d'afficher le nombre de personnes navigant sur ton site avec Netscape 4.
En plus d'être inutile, cela prend des ressources.
Par contre, si tu persistes, essayes de mettre un ou plusieurs index sur la grosse table.
 
WRInaute discret
On peut d'une part utiliser inet_aton() ou ip2long(), d'autre part voir si la base ip2country n'est pas plus rapide ou utiliser hostip.info, ou encore utiliser Net_GeoIP ...
Tout cela n'est pas très fiable, tout dépend de l'utilisation qu'on en fait.
Il est parfois plus rapide de traiter les informations une à une plutôt que par lots, ne pas tenir compte du z et même du y pour grouper les IP et limiter le nombre de requêtes.
 
WRInaute passionné
en fait, je pense que c'est très simple : Tu n'affiches PAS le nombre de personnes connectées.
C'est complétement passé de mode.

Je ne crois pas du tout, ce n'est pas une question de mode !
Je ne conçois pas un forum sans savoir qui est la, combien il y en a.

Or mon site a aussi un forum programmé entièrement par moi, il évolue, et je compte rajouter cette fonctionnalité.

Donc pour moi, aucune question de fashion, de mode, ou de web 1 ou 2 ou 3 et ce que tu veux.

Juste une information pratique surtout pour forums ou site genre réseau sociaux, site de rencontre et j'en passe des exemples


@Dan_A
Merci, bon je ne comprends rien, mais je vais rechercher toutes ces fonctions et voir leur utilités :)

La en revanche, afficher l'IP et le pays de la personne est un suppléênt pas necessaire, je suis d'accord, mais c'est personnel, pour ne pas mourir idiot, cela ne veux pas dire que je le mettrais ...

Merci à tous
 
WRInaute passionné
Alors pense aux index si tu continues dans cette voie.
- Les index permettent de diminuer de manière drastique la charge serveur. Il faut bien les choisir pour que cela soit efficace : cela peut être 1 champ, ou plusieurs, cela dépend de ta requête, et l'ordre dans lesquels tu les choisis est important).
- Essaye de faire le maximum de chose via MySQL et de ressortir sur le résultat : une liste triée de X colonnes, que t'aura juste à parcourir en PHP sans charge. Aide toi d'une procédure stockée (MySQL >= 5) ou d'une fonction dans MySQL.
 
WRInaute passionné
100 000 c'est pas non plus une très grosse table ou alors en comparaison avec les autres de la BD peut être, mais les index devraient normalement bien t'aider comme l'a dit loran750.
 
WRInaute passionné
Juste une remarque (en plus de ce que j'ai dit), j'y pense depuis ce matin, mais 20 secondes (même 10 secondes), je trouve ça énorme. Dit moi, tu ne ferai pas des allers-retours PHP <--> MySQL par hasard ? ( X appels à MySQL pour X visiteurs).

Le temps de traitement se retrouve démultiplié ( grosso modo : temps de traitement de la bouche en PHP + X fois le temps d'accès et le temps de traitement MySQL).
 
WRInaute passionné
Bin je ne sais pas, j'ai juste deux boucles imbriquée comme je l'ai expliqué.

Moi je pensais que c'était parce que lors de la deuxième boucle il y a une grosse base, et ce n'est pas juste une ligne à chercher, il faut chercher la ligne dont le numéro est compris entre deux nombre

D'ailleurs dans la requête
SELECT ip_country FROM geoip WHERE $ipnum >= begin_ip_num AND $ipnum <= end_ip_num LIMIT 1

il y a un index sur les champs begin_ip_num et begin_ip_num

Sinon loran750, explique moi ton truc d'aller retour PHP SVP
Pour l'instant oui, à chaque fois qu'on va sur la page, la double boucle est effectué, en même temps, il n'y a que moi qui connaissait cette page :)

Sinon je veux bien une solution pour limiter l'exécution de requêtes

Merci
 
WRInaute passionné
et bien, ce que je veux dire c'est que tu as probablement la chose suivante :

<?php

for (variable;condition de sortie; avancement) {
....
$ipnum = ... quelque chose ....
mysql_query ("SELECT ip_country FROM geoip WHERE $ipnum >= begin_ip_num AND $ipnum <= end_ip_num LIMIT 1");
$mysql_result = ... traitement ...

}
?>

et donc c'est ça qui plombe ton traitement. Cela fait autant d'accès à la BDD (même si la connexion est ouverte au premier accès) que de boucles.

Tu dois trouver le moyen d'envoyer en une fois les infos à Mysql.
 
WRInaute passionné
Oui, et cela est fait 200 fois si j'ai 200 visiteurs connectés.

Mais je ne vois pas comment faire autrement...

Si tu as une idées...
En tout cas merci pour l'aide
 
WRInaute passionné
Ah oui, donc c'est chaud.

Il faut que tu "montes" le maximum d'infos dans MySQL.
Je connais pas ton script mais sache que tu peux faire des fonctions (avec des conditions, des boucles, ...) et des procédures stockées en MySQL...

Tiens, voilà une idée vite faite (mais mauvaise) :
tu concatènes tes données en input dans une chaine de caractères, peu importe le séparateur (dans l'exemple "1,2,3,4,5" avec une virgule).
Ensuite, dans une fonction SQL, tu "déconcatènes" les données et tu fais ta boucle et ton traitement. Quand t'as fini, tu as une liste ordonnée avec TOUS tes résultats que tu renvoies à PHP, qui se contente de les afficher...
 
Discussions similaires
Haut