Question

J'ai deux tables, une pour les routes et un pour les aéroports.

Routes contient un peu plus de 9000 lignes et moi-même avons indexé chaque colonne. Aéroports seulement 2000 lignes et moi-même avons également indexé chaque colonne.

Quand je lance cette requête, il peut prendre jusqu'à 35 secondes pour revenir à 300 lignes:

SELECT routes.* , a1.name as origin_name, a2.name as destination_name FROM routes
LEFT JOIN airports a1 ON a1.IATA = routes.origin
LEFT JOIN airports a2 ON a2.IATA = routes.destination
WHERE routes_build.carrier = "Carrier Name"

L'exécution avec « DESCRIBE » Je reçois l'information followinf, mais je ne suis pas 100% sûr de ce qu'il me dit.

id | Select Type   | Table             | Type   | possible_keys        | Key            | Key_len   | ref    | rows     | Extra
--------------------------------------------------------------------------------------------------------------------------------------
1  | SIMPLE        | routes_build      | ref    | carrier,carrier_2    | carrier        | 678       | const  | 26       | Using where
--------------------------------------------------------------------------------------------------------------------------------------
1  | SIMPLE        | a1                | ALL    | NULL                 | NULL           | NULL      | NULL   | 5389     |
--------------------------------------------------------------------------------------------------------------------------------------
1  | SIMPLE        | a2                | ALL    | NULL                 | NULL           | NULL      | NULL   | 5389     |
--------------------------------------------------------------------------------------------------------------------------------------

La seule alternative que je peux penser est d'exécuter deux requêtes distinctes et les rejoindre avec PHP bien, je ne peux pas croire quelque chose comme ça quelque chose qui pourrait être tuer un serveur MySQL. Donc, comme d'habitude, je pense que je fais quelque chose de stupide. SQL est mon numéro 1 faiblesse.

Était-ce utile?

La solution

part, je voudrais commencer par retirer la gauche jointures et les remplacer par des jointures internes que chaque liaison doit avoir un point de début et fin.

Autres conseils

Il vous dit qu'il est de ne pas utiliser un index pour se joindre à la table des aéroports. Voyez comment la colonne « lignes » est si énorme, 5000 impair? qui est le nombre de lignes qu'il est d'avoir à lire pour répondre à votre requête.

Je ne sais pas pourquoi, comme vous avez demandé que vous avez indexé chaque colonne. Qu'est-ce que l'IATA? Est-il unique? Je crois que si MySQL décide de l'indice est inefficace, il peut l'ignorer.

EDIT: si l'IATA est une chaîne unique, peut-être essayer la moitié d'indexation seulement? (Vous pouvez sélectionner le nombre de caractères à l'index) qui peut donner un indice MySQL peut utiliser.

SELECT  routes.*, a1.name as origin_name, a2.name as destination_name
FROM    routes_build
LEFT JOIN
        airports a1
ON      a1.IATA = routes_build.origin
LEFT JOIN
        airports a2
ON      a2.IATA = routes_build.destination
WHERE   routes_build.carrier = "Carrier Name"

De votre EXPLAIN PLAN je peux voir que vous ne disposez pas d'un index sur airports.IATA.

Vous devez créer pour la requête de travailler rapidement.

nom l'indique également qu'il devrait être un indice de UNIQUE, puisque les codes sont uniques IATA.

Mise à jour:

S'il vous plaît poster votre définition de la table. Émettre cette requête pour le montrer:

SHOW CREATE TABLE airports

Aussi je note que votre index sur FULLTEXT est inutile, sauf si ft_max_word_len vous avez défini la configuration est MySQL à 3 ou moins 4.

Par défaut, il est <=>.

<=> codes sont des caractères à long <=>, et ne cherche pas <=> pour ces mots courts en utilisant des paramètres <=> par défaut.

Après avoir implémenté d'excellents conseils de Martin Robins (c.-à supprimer toutes les occurrences du mot de votre recherche LEFT), essayez de donner un indice de routes_build composé sur carrier, origin et destination.

Cela dépend vraiment de ce que l'information que vous essayez d'atteindre. Vous n'avez probablement pas besoin de se joindre aéroports deux fois et vous n'avez pas besoin probablement d'avoir recours aux jointures gauche. En outre, si vous pouvez effectuer une recherche sur un champ numérique plutôt que d'un champ de texte, qui permettrait d'accélérer les choses aussi bien.

Alors, qu'est-ce que vous essayez de chercher?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top