0
votes

Rejoindre intérieur dans MySQL prendre beaucoup de temps

J'ai des contacts de table avec plus de 1 000 000 et d'autres villes de table qui ont environ 20 000 enregistrements. Besoin d'aller chercher toutes les villes qui ont utilisé dans la table des contacts. Les contacts Tableau ont suivi des colonnes ID, nom, téléphone, email, ville, état, pays, postal, adresse, manager_id table des villes ont Id, ville

J'ai utilisé une jointure intérieure pour cela, mais sa peine de partir. La requête prend plus de 2 minutes pour exécuter.

J'ai utilisé cette requête xxx

index créé sur gestionnaire_id. Mais toujours c'est très lent.


2 commentaires

Les indices sur les champs City peuvent être plus utiles, mais vraiment, Contacts doit être référencé villes.id plutôt que villes.City ; pour des comparaisons entière plus rapides.


Avez-vous des index sur les champs des villes?


6 Réponses :


0
votes

On dirait que vous devez ajouter deux index, un sur villes.City et un sur (contacts.manager_id, contacts.City) . Cela devrait accélérer les choses de manière significative.


2 commentaires

L'index devrait être basé sur la composante admissible. Dans ce cas, contacts avec un gestionnaire spécifique. La ville est juste une venue pour le résultat.


@Drapp Oui, vous avez raison. J'ai mis à jour ma réponse. Peut-être que j'étais un peu trop rapide pour répondre. Là encore, une simple requête comme celle-ci, même avec ces rangées de rangée de table, ne doit pas prendre 120 secondes. Pas même 120 millisecondes.



1
votes

Pour de meilleures performances, vous pouvez ajouter Index

sur la colonne Villes de table Ville

On Table Contacts Un index composite sur les colonnes (manager_id, ville)


6 commentaires

@MarlinPierce. pourrait être .. Répondez mis à jour .. merci


Merci, mais problème est que la table des contacts comportant presque 20 colonnes et 5 colonnes simples ont déjà indexé et 2 index composite, est-il préférable d'utiliser de nombreux index sur une table


Vous devez évaluer la requête que vous avez vraiment besoin d'améliorer les performances et la requête la plus utilisée et appliquez les index sur la base de ces évaluations .. Pour améliorer les performances dans SQL, vous avez besoin d'index .. Mais vous devez équilibrer le nombre d'index respectés vos besoins réels


@MarlinPierce, pouvez-vous s'il vous plaît également expliquer, comment avoir le gestionnaire_id d'abord être plus rapide?


@ user3337590 .. L'utilisation de gestionnaire_id comme première colonne de l'index liée au fait que vous avez une valeur littérale dans votre clause où se trouve la clause du lieu où la clause de l'endroit où la clause et la teneur en index peuvent réduire le nombre de rangées numérisées dans le Index et améliorer les performances (espérons que mon commentaire est clair)


@Ankitbajpai user3337590 et Drapp expliqua.



0
votes

Vous avez besoin de deux index, un sur chaque table.

sur la table Contacts , premier index manager_id , puis Ville xxx

sur les villes table , juste index `ville.


2 commentaires

Merci, mais problème est que la table des contacts comportant presque 20 colonnes et 5 colonnes simples ont déjà indexé et 2 index composite, est-il préférable d'utiliser de nombreux index sur une table


Pour cette requête, si vous avez un index sur (gestionnaire_id, ville) Cette requête ne utilisera aucun autre index. (les index peuvent toutefois être utilisés pour d'autres requêtes.)



1
votes

Filtre Contacts CODE> Tout d'abord, puis rejoindre vers Villes CODE>:

SELECT ct.* 
FROM cities ct INNER JOIN (
  SELECT city FROM contacts
  WHERE manager_Id = 1
) cn ON cn.city = ct.city


7 commentaires

Pensez-vous que au lieu d'avoir 2 index différents sur la ville et le gestionnaire_ID sur la table des contacts, il suffirait que 1 index composite comme (ville, manager_id) serait mieux?


Non, pas dans ce cas.


Puissiez-vous s'il vous plaît expliquer la raison pour la même chose?


Un index pour gestionnaire_id est nécessaire pour la filtration des contacts (où Manager_id = 1). Les 2 autres index de chaque table pour la jointure sur cn.City = ct.City. Je ne vois pas pour cette requête la nécessité d'un index composite.


Un index composite (gestionnaire_id, ville) pourrait être meilleur. Cependant, la seule façon réelle de dire est d'essayer à la fois des solutions et de comparer la sortie de Expliquer une sélection étendue ...


Merci d'avoir aidé, c'est beaucoup plus rapide avec l'index composite (gestionnaire_id, ville) sur la table des contacts uniquement, mais si vous utilisez 2 index différents pour une colonne unique, ce n'est pas beaucoup plus rapide


@ user3337590 Pour ma requête et pour filtrer la table des contacts: où manager_id = 1, l'indice composite n'est pas utile.



0
votes

est le champ "ville" de la table "Contacts" A Varchar?

Si c'est le cas, je vois plusieurs choses ici. Tout d'abord, puisque vous avez déjà l'identité de la ville correspondante de vos tables "villes", je ne vois pas pourquoi ne pas utiliser la même "ID" de la table "Villes" pour la table "Contacts" .

Vous pouvez ajouter le champ "IDCITY" à la table "Contacts" afin que vous ne puissiez pas modifier vos enregistrements existants. Vous devrez insérer le «IDCITY» manuellement pour chacun de vos enregistrements, ou vous pouvez créer une requête à l'aide de la table des «villes», puis comparez l'identité »mais insérez la« ville »(nom de la ville) dans vos» contacts 'Tableau.

retour à votre requête: Ensuite, utilisez une jointure INT au lieu d'une jointure Varcharne. Depuis que vous avez de nombreux enregistrements, cela peut apparaître une importance importante dans la performance.


0 commentaires

1
votes

Comme d'autres ont souligné avoir l'indice approprié, je prends un peu plus de clarification. Vous recherchez spécifiquement des contacts où le gestionnaire ID = 1. Cela ne devrait pas être une personne, mais pourrait être de nombreuses personnes. Donc, avoir l'identifiant du gestionnaire dans la première position optimisera-moi, obtenez-moi toutes les personnes pour ce manager. En ayant la ville dans le cadre de l'indice via (Manager_id, Ville), vous tirez les deux éléments de données dont vous avez besoin pour optimiser dans le cadre de l'index. De cette façon, le moteur n'a pas besoin d'aller aux pages de données brutes pour obtenir l'autre partie d'intérêt.

Maintenant, de cela, vous voulez toutes les informations de la ville (d'où la jointure à la table de la ville sur cet identifiant). P>

Puisque vous ne faites que interroger les villes et non les informations de contact actuelles, vous voulez probablement avoir une carte de ville distincte. Disons qu'un gestionnaire est responsable de 50 personnes et la plupart d'entre eux vivent dans la même ville ou voisin. Vous pouvez avoir 5 villes distinctes? Cela aussi limitera votre ensemble de résultats de jointure. P>

Dit dire que, je ferais un suivi, et avec MySQL, en utilisant de droite_join peut aider à optimiser par "faire la requête comme je l'ai écrite, ne pensez pas Pour moi ". P>

select STRAIGHT_JOIN
      cty.*
   from
      ( select distinct c.City
           from Contacts c
           where c.Manager_ID = 1 ) PQ
         JOIN Cities cty
            on PQ.City = Cty.City


0 commentaires