Récemment j'ai eu ce question, et tout a fonctionné correctement jusqu'à ce que je l'ai envoyé à mon serveur chez DreamHost.Comment puis-je améliorer les performances de cette requête?
La requête ci-dessous semble prendre trop de temps à s'exécuter et je n'arrive pas à comprendre pourquoi tant de lignes sont traitées en même temps. Dans mon serveur local, la même requête a été exécutée en 0,3 seconde.
SELECT feed_entries . *
FROM feed_entries
WHERE
id
IN (
SELECT e.id
FROM feed_entries AS e
INNER JOIN feeds AS f ON e.feed_id = f.id
INNER JOIN entries_categorias AS ec ON ec.entry_id = e.id
INNER JOIN categorias AS c ON ec.categoria_id = c.id
WHERE
e.deleted =0
AND
c.slug
IN ('entenda', 'google')
GROUP BY e.id
HAVING COUNT(DISTINCT ec.id) =2
)
ORDER BY date DESC
LIMIT 1
C'est le message que je l'ai reçu de l'équipe de soutien:
Eh bien, il ressemble à ce que la requête est verrouillé en raison de ces requêtes comme celui-ci, le traitement 6.5 millions dossiers, pendant 11 secondes.
# Query_time: 11.639269 Lock_time: 0.000192 Rows_sent: 2 Rows_examined:
6509098
use desenvolvimentistas;
SET timestamp=1280325753;
SELECT `e`.*, `f`.`titulo` AS `feedTitulo`, `f`.`url` AS `feedUrl` FROM
`feed_entries` AS `e`
INNER JOIN `feeds` AS `f` ON e.feed_id =f.id WHERE (e.id IN (SELECT
`e`.`id` FROM `feed_entries` AS `e`
INNER JOIN `feeds` AS `f` ON e.feed_id =f.id
INNER JOIN `entries_categorias` AS `ec` ON ec.entry_id =e.id
INNER JOIN `categorias` AS `c` ON ec.categoria_id =c.id WHERE (e.deleted
=0) AND (e.id NOT IN ('', '', '842', '853', '774', '878')) AND
(e.imagem145x145 =1) AND (c.slug IN('destaque-2')) GROUP BY `e`.`id`
HAVING (COUNT(DISTINCT ec.id) =1))) ORDER BY `e`.`date` DESC LIMIT 4;
probablement la requête prend .3 secondes pour exécuter sur votre machine locale qui est ralenti, mais il est lent sur nos serveurs car il est en cours d'exécution de la requête 150 à un temps, et chacun traite 15,3 millions d'enregistrements.
moi avions mysql admin a pris un coup d'œil à et il a dit qu'il était tout à fait inefficace et a été surpris de constater que la base de données était même accessible parce que les requêtes avaient tellement enfermés. Il a déclaré que la base de données sera désactivée si continue ainsi et cause problèmes de serveur. Il a dit que vous devriez réparer les lignes examinées ou obtenir un MySQL PS, bien qu'un mysql ps ne le corrigera pas , mais empêchera plutôt la base de données d'être désactivée.
Voici la requête:
# Query_time: 25.944779 Lock_time: 0.000176 Rows_sent: 0 Rows_examined:
15378209
use desenvolvimentistas;
SELECT `feed_entries`.* FROM `feed_entries` WHERE (id IN (SELECT `e`.`id`
FROM `feed_entries` AS `e` INNER JOIN `feeds` AS `f` ON e.feed_id =f.id
INNER JOIN `entries_categorias` AS `ec` ON ec.entry_id =e.id INNER JOIN
`categorias` AS `c` ON ec.categoria_id =c.id WHERE (e.deleted =0) AND
(c.slug IN('entenda','google')) GROUP BY `e`.`id` HAVING (COUNT(DISTINCT
ec.id) =2))) ORDER BY `date` DESC LIMIT 1;
Voici une autre qui doit être fixé:
# Query_time: 27.010857 Lock_time: 0.000165 Rows_sent: 0 Rows_examined:
15382750
use desenvolvimentistas;
SET timestamp=1280325706;
SELECT `e`.*, `f`.`titulo` AS `feedTitulo`, `f`.`url` AS `feedUrl` FROM
`feed_entries` AS `e`
INNER JOIN `feeds` AS `f` ON e.feed_id =f.id WHERE (e.id IN (SELECT
`e`.`id` FROM `feed_entries` AS `e`
INNER JOIN `feeds` AS `f` ON e.feed_id =f.id
INNER JOIN `entries_categorias` AS `ec` ON ec.entry_id =e.id
INNER JOIN `categorias` AS `c` ON ec.categoria_id =c.id WHERE (e.deleted
=0) AND (c.slug IN('manchete', 'google')) GROUP BY `e`.`id` HAVING
(COUNT(DISTINCT ec.id) =2))) ORDER BY `e`.`date` DESC LIMIT 4;7:18
Serait-ce une bonne suggestion d'avoir un index sur 'date' aussi, étant donné qu'il passe commande mais ne prend que le meilleur résultat? –
@Neil Trodden: Oui, mais [MySQL a une limite d'espace pour l'allocation d'index (1 000 pour MyISAM, 767 pour InnoDB)] (http://dev.mysql.com/doc/refman/5.0/fr/create-index .html) donc les critères JOIN sont ma première priorité, puis voir ce que je peux faire avec la couverture des index. –
Merci, j'ai réduit le nombre de 150 requêtes et défini les index. Ont également découvert d'autres erreurs. Maintenant c'est bon. –