2013-05-18 3 views
2

J'utilise un CMS, mais cela n'a rien à voir avec ça.Une mise à jour très lente vers un serveur MySQL

J'ai une requête simple qui est:

UPDATE e107_online SET `online_location` = 'http://page.com/something.php?', `online_pagecount` = 133 WHERE `online_ip` = '175.44.*.*' AND `online_user_id` = '0' LIMIT 1; 

mais la même requête rapporté de mon assistance du site Web donne que:

[email protected]: cosyclim_website[cosyclim_website] @ localhost [] 

Thread_id: 7493739 Schema: cosyclim_website 

Query_time: 12.883518 Lock_time: 0.000028 Rows_sent: 0 Rows_examined: 0 Rows_affected: 1 Rows_read: 1 

Il faut 12 (presque 13) secondes pour une simple mise à jour question? Y a-t-il un moyen de l'optimiser en quelque sorte? Si je le lance sur PhpMyAdmin, cela prend 0,0003s.

Le tableau:

CREATE TABLE IF NOT EXISTS `e107_online` (
    `online_timestamp` int(10) unsigned NOT NULL default '0', 
    `online_flag` tinyint(3) unsigned NOT NULL default '0', 
    `online_user_id` varchar(100) NOT NULL default '', 
    `online_ip` varchar(15) NOT NULL default '', 
    `online_location` varchar(255) NOT NULL default '', 
    `online_pagecount` tinyint(3) unsigned NOT NULL default '0', 
    `online_active` int(10) unsigned NOT NULL default '0', 
    KEY `online_ip` (`online_ip`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+0

Vous êtes sûr que le site Web est connecté au même DB que PhpMyAdmin? – Wiktor

+0

Oui, j'utilise un hébergement mutualisé et seulement 1 DB, car mon site web est petit. – Nikola

+0

@Nikola Courez-vous phpMyAdmin sur l'hôte en direct ou sur votre machine locale? Assurez-vous et dites-moi – itsols

Répondre

3

Votre requête est mise à jour d'une ligne qui répond à certains critères:

UPDATE e107_online 
    SET `online_location` = 'http://page.com/something.php?', `online_pagecount` = 133 
    WHERE `online_ip` = '175.44.*.*' AND `online_user_id` = '0' 
    LIMIT 1; 

Étant donné que vous avez des adresses IP, je suppose que ce tableau est assez grand. Des millions et des millions et des millions de lignes. Il existe de nombreuses raisons pour lesquelles une mise à jour peut prendre beaucoup de temps, comme le chargement du serveur, le blocage des transactions et les performances du fichier journal. Dans ce cas, faisons l'hypothèse que le problème est de trouver l'une des lignes. Vous pouvez tester cela en faisant un select avec les mêmes conditions et voir combien de temps cela prend.

En supposant que select est systématiquement lent, le problème peut probablement être résolu avec des index. Si la table n'a pas d'index (ou si MySQL ne peut pas utiliser d'index existants), elle doit effectuer une analyse de table complète. Et, peut-être le seul enregistrement qui correspond est à la fin de la table. Ça prend du temps pour le trouver.

Je suggère d'ajouter un index sur e107_online(online_ip) ou e107_online(online_user_id, online_ip) pour l'aider à trouver l'enregistrement plus rapidement. L'index doit être un index b-tree, comme expliqué here. Une des conséquences de l'utilisation d'un index est que l'ip avec la plus petite valeur correspondante sera probablement celle choisie. Je ne sais pas si ce manque de hasard fait une différence dans votre application.

+0

J'ai ajouté la table sur mon post. Je n'ai pas des millions de disques, j'ai <50, parce que mon site web n'est pas vraiment rempli. Comme j'ai répondu à @itsols j'exécute une requête sur chaque page qui est ouverte qui est: SUPPRIMER DE e107_tmp WHERE tmp_time <1368887690 ET tmp_ip! = 'Données' AND tmp_ip! = 'Submitted_link' Ce n'est pas le mien système, c'est e107, qui est un CMS gratuit, mais leur aide sur les forums n'est pas quelque chose que vous pouvez vraiment compter sur:/ – Nikola

+0

Je voudrais également vérifier pour tout type de casting. J'ai remarqué un contrôle online_user_id = '0'. Si online_user_id est une colonne numérique, est-ce que MySQL pourrait analyser '0' de la chaîne en entier pour chaque ligne qu'elle analyse? Pourrait être petit poisson, mais pourrait être des fruits à portée de main ... – Brandon

+0

bien user_id = 0 est utilisé pour les personnes qui ne sont pas connectés (invités), il n'a jamais été casté – Nikola

0

Est-ce que cette requête est lente ou les requêtes de votre site Web sont-elles généralement plus lentes? phpMyAdmin exécute très probablement des requêtes directement sur la machine sur laquelle vit votre base de données, ce qui signifie que la latence réseau est effectivement de 0ms. Je vous aurais suggéré d'ajouter un index incluant les deux colonnes dans votre clause WHERE, mais avec < 50 lignes cela n'a aucun sens. Cela va se traduire par un blocage entre votre site Web et le serveur de base de données.

Assurez-vous également que vous ne faites rien de stupide comme de courir sans que la mise en commun des connexions ne soit activée (ou de créer une tonne de connexions inutilement). J'ai vu des pools de connexion qui manquaient d'espace causer des problèmes similaires.

+0

Eh bien, j'ai demandé à mon fournisseur d'hébergement pour montrer mon pourquoi j'ai un si grand temps d'utilisation de cpu mysql. Et ils m'ont donné deux requêtes lentes - celle-ci et une autre (même type, même tableau etc). Habituellement, j'ai environ ~ 30-40 requêtes (<60 pour sûr) par page et cela prend (selon l'utilisation du temps intégré du CMS: Temps de rendu: 0.1416 sec, 0.1159 de cela pour les requêtes. – Nikola

Questions connexes