2009-10-15 7 views
0

J'ai récemment remarqué qu'une requête que j'utilise fonctionne assez lentement, à presque 1 seconde par requête.index et accélération des requêtes 'dérivées'

La requête ressemble à ceci

 
SELECT eventdate.id, 
     eventdate.eid, 
     eventdate.date, 
     eventdate.time, 
     eventdate.title, 
     eventdate.address, 
     eventdate.rank, 
     eventdate.city, 
     eventdate.state, 
     eventdate.name, 
     source.link, 
     type, 
     eventdate.img 
FROM source 
RIGHT OUTER JOIN 
(
    SELECT event.id, 
      event.date, 
      users.name, 
      users.rank, 
      users.eid, 
      event.address, 
      event.city, 
      event.state, 
      event.lat, 
      event.`long`, 
      GROUP_CONCAT(types.type SEPARATOR ' | ') AS type 
    FROM event FORCE INDEX (latlong_idx) 
    JOIN users ON event.uid = users.id 
    JOIN types ON users.tid=types.id 
    WHERE `long` BETWEEN -74.36829174058 AND -73.64365405942 
    AND lat BETWEEN 40.35195025942 AND 41.07658794058 
    AND event.date >= '2009-10-15' 
    GROUP BY event.id, event.date 
    ORDER BY event.date, users.rank DESC 
    LIMIT 0, 20 
)eventdate 
ON eventdate.uid = source.uid 
AND eventdate.date = source.date; 

et l'expliquer est

 
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+ 
| id | select_type | table  | type | possible_keys | key   | key_len | ref       | rows | Extra       | 
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+ 
| 1 | PRIMARY  |   | ALL | NULL   | NULL  | NULL | NULL       | 20 |         | 
| 1 | PRIMARY  | source  | ref | iddate_idx | iddate_idx | 7  | eventdate.id,eventdate.date | 156 |         | 
| 2 | DERIVED  | event  | ALL | latlong_idx | NULL  | NULL | NULL       | 19500 | Using temporary; Using filesort | 
| 2 | DERIVED  | types  | ref | eid_idx  | eid_idx  | 4  | active.event.id    | 10674 | Using index      | 
| 2 | DERIVED  | users  | eq_ref | id_idx  | id_idx  | 4  | active.types.id    |  1 | Using where      | 
+----+-------------+------------+--------+---------------+-------------+---------+------------------------------+-------+---------------------------------+ 

J'ai essayé d'utiliser « indice de force » sur latlong, mais cela ne semble pas accélérer les choses à tout.

Est-ce la table dérivée qui provoque les réponses lentes? Si oui, y a-t-il un moyen d'améliorer la performance de ceci?

-------- ------------- EDIT J'ai essayé d'améliorer la mise en forme pour le rendre plus lisible, ainsi

je lance le même requête changeant seulement la « instruction WHERE que

 
WHERE users.id = (
SELECT users.id 
FROM users 
WHERE uidname = 'frankt1' 
ORDER BY users.approved DESC , users.rank DESC 
LIMIT 1) 
AND date & gt ; = '2009-10-15' 
GROUP BY date 
ORDER BY date) 

Cette requête est exécutée en 0.006 secondes

l'expliquer ressemble

 
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+ 
| id | select_type | table  | type | possible_keys | key   | key_len | ref       | rows | Extra   | 
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+ 
| 1 | PRIMARY  |   | ALL | NULL   | NULL   | NULL | NULL       | 42 |    | 
| 1 | PRIMARY  | source  | ref | iddate_idx | iddate_idx | 7  | eventdate.id,eventdate.date | 156 |    | 
| 2 | DERIVED  | users  | const | id_idx  | id_idx  | 4  |        | 1 |    | 
| 2 | DERIVED  | event  | range | eiddate_idx | eiddate_idx | 7  | NULL       | 24 | Using where | 
| 2 | DERIVED  | types  | ref | eid_idx  | eid_idx  | 4  | active.event.bid    | 3 | Using index | 
| 3 | SUBQUERY | users  | ALL | idname_idx | idname_idx | 767  |        | 5 | Using filesort | 
+----+-------------+------------+-------+---------------+---------------+---------+------------------------------+------+----------------+ 
+0

Améliorer la formation du code. Ajouter des indentations, supprimez les champs inutiles de SELECT. –

Répondre

1

La seule façon de nettoyer cette instruction SQL gigantesque est de revenir à la planche à dessin et de travailler avec précaution sur la conception et les besoins de votre base de données. Dès que vous commencez à joindre 6 tables et que vous utilisez un select interne, vous devriez vous attendre à des temps d'exécution incroyables. Pour commencer, assurez-vous que tous vos champs id sont indexés, mais mieux vaut vérifier que votre conception est valide. Je ne sais pas où commencer à regarder votre SQL - même après que je l'ai reformaté pour vous.

Notez que l'utilisation d'index signifie que vous devez émettre les instructions correctes lorsque vous créez ou modifiez les tables que vous utilisez. Voir par exemple MySql 5.0 create indexes

+1

rejoindre 6 ables n'est PAS une grosse jointure. Rejoindre 6 tables avec les bons index ne devrait pas être un problème ... –

+0

merci Mitch, je ne pensais pas qu'une table 6 join était hors de question, comme je reçois la même requête avec une autre déclaration 'WHERE' et obtenir 0,006 secondes temps de réponse. – pedalpete

Questions connexes