2009-03-02 7 views
0

J'ai rencontré un problème la semaine dernière en passant de dev-testing où une de mes requêtes qui fonctionnait parfaitement dans dev, rampait sur mon serveur de test.Les requêtes MySQL explorent lors du changement de serveurs

Il a été corrigé en ajoutant FORCE INDEX sur l'un des index de la requête.

Maintenant, j'ai chargé la même base de données sur le serveur de production (et il fonctionne avec la commande FORCE INDEX, et il a ralenti à nouveau.

Toute idée de ce qui causerait quelque chose comme cela se produise? Les tests et prod sont tous deux en cours d'exécution le même système d'exploitation et la version de MySQL (contrairement à la dev).

est ici la requête et l'expliquer de celui-ci.

EXPLAIN SELECT showsdate.bid, showsdate.bandid, showsdate.date, showsdate.time, 
    -> showsdate.title, showsdate.name, showsdate.address, showsdate.rank, showsdate.city, showsdate.state, 
    -> showsdate.lat, showsdate.`long` , tickets.link, tickets.lowprice, tickets.highprice, tickets.source 
    -> , tickets.ext, artistGenre, showsdate.img 
    -> FROM tickets 
    -> RIGHT OUTER JOIN (
    -> SELECT shows.bid, shows.date, shows.time, shows.title, artists.name, artists.img, artists.rank, artists 
    -> .bandid, shows.address, shows.city, shows.state, shows.lat, shows.`long`, GROUP_CONCAT(genres.genre SEPARATOR 
    -> ' | ') AS artistGenre 
    -> FROM shows FORCE INDEX (biddate_idx) 
    -> JOIN artists ON shows.bid = artists.bid JOIN genres ON artists.bid=genres.bid 
    -> WHERE `long` BETWEEN -74.34926984058 AND -73.62463215942 AND lat BETWEEN 40.39373515942 AND 41.11837284058 
    -> AND shows.date >= '2009-03-02' GROUP BY shows.bid, shows.date ORDER BY shows.date, artists.rank DESC 
    -> LIMIT 0, 30 
    ->)showsdate ON showsdate.bid = tickets.bid AND showsdate.date = tickets.date; 
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+--------+----------------------------------------------+ 
| id | select_type | table  | type | possible_keys | key   | key_len | ref       | rows | Extra          | 
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+--------+----------------------------------------------+ 
| 1 | PRIMARY  | <derived2> | ALL | NULL   | NULL  | NULL | NULL       |  30 |            | 
| 1 | PRIMARY  | tickets | ref | biddate_idx | biddate_idx | 7  | showsdate.bid,showsdate.date |  1 |            | 
| 2 | DERIVED  | genres  | index | bandid_idx | bandid_idx | 141  | NULL       | 531281 | Using index; Using temporary; Using filesort | 
| 2 | DERIVED  | shows  | ref | biddate_idx | biddate_idx | 4  | activeHW.genres.bid   |  5 | Using where         | 
| 2 | DERIVED  | artists | eq_ref | bid_idx  | bid_idx  | 4  | activeHW.genres.bid   |  1 |            | 
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+--------+----------------------------------------------+ 

Répondre

3

Je pense que je renchérit quand vous avez posé la question sur les différences en dev -> test

Avez-vous essayé de reconstruire les index et de recalculer les statistiques? Généralement, forcer un index est une mauvaise idée car l'optimiseur fait généralement de bons choix quant aux index à utiliser. Cependant, cela suppose qu'il a de bonnes statistiques et que les index ne sont pas sérieusement fragmentés.

ETA:

Pour Reconstruire les index, utilisez:

REPAIR TABLE tbl_name QUICK; 

Recalculer statistiques:

ANALYZE TABLE tbl_name; 
+0

Vous supposez que le type de table est de MyISAM et non InnoDB - REPAIR TABLE est uniquement applicable au moteur MyISAM. InnoDB n'a pas de commande comparable. –

+0

Il s'agit d'un DB MyISAM, et j'avais exécuté «optimiser» car je pensais que c'était ce que je devais faire. J'ai maintenant exécuté à la fois réparer et analyser sur les deux tables. grande amélioration, mais en quelque sorte mon dev & test machines sont encore plus rapides que prod. Prod. 39 sec, dev. 18 sec. – pedalpete

+0

@Cody - Vous avez raison. Pour faire cela pour InnoDB, vous utiliseriez simplement une instruction ALTER factice. Quelque chose comme ALTER TABLE my_table TYPE = 'InnoDB'. –

0

Est-ce que serveur de test ont seulement 10 enregistrements et serveur de production 1000000000 records? Cela peut également provoquer des temps d'exécution différents

0

Les deux serveurs sont-ils configurés de la même manière? Il semble que vous traversiez un «point de basculement» dans la performance de MySQL. Je comparerais les configurations de MySQL; il pourrait y avoir un paramètre de mémoire différent.

Questions connexes