Question

J'ai une requête particulièrement lente en raison de la grande quantité d'informations étant reliées entre elles. Cependant, je besoin d'ajouter une clause where sous la forme d'id dans (select id de la table).

Je veux savoir s'il y a un gain de ce qui suit, et plus pressant, va encore donner les résultats souhaités.

select a.* from a where a.id in (select id from b where b.id = a.id)

comme une alternative à:

select a.* from a where a.id in (select id from b)

Mise à jour: MySQL Ne peut pas être plus précis désolé un tableau est effectivement une jointure entre 7 tables différentes. utilisation de * est des exemples

Modifier, b ne soit pas sélectionné

Était-ce utile?

La solution

Votre question portait sur la différence entre ces deux:

select a.* from a where a.id in (select id from b where b.id = a.id)

select a.* from a where a.id in (select id from b)

Le premier est un corrélé sous-requête. Il peut provoquer MySQL pour exécuter la sous-requête pour chaque ligne de a.

Celui-ci est un non corrélé sous-requête. MySQL devrait être en mesure d'exécuter une fois et mettre en cache les résultats pour la comparaison avec chaque ligne de <=>.

Je voudrais utiliser ce dernier.

Autres conseils

Les deux requêtes que vous énumérez sont l'équivalent de:

select a.* 
from a 
inner join b on b.id = a.id

Presque tous les optimiseurs seront les exécuter de la même manière.

Vous pouvez poster un véritable plan d'exécution, et que quelqu'un ici peut vous donner un moyen d'accélérer. Il aide si vous spécifiez quel serveur base de données que vous utilisez.

YMMV, mais je l'ai souvent trouvé avec exists au lieu de requêtes fait courir plus vite.

SELECT a.* FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)

Bien sûr, sans voir le reste de la requête et le contexte, cela peut ne pas faire plus rapidement la requête.

peut être une joint à option plus préférable, mais si a.id apparaît plusieurs fois dans la colonne id b, vous devez jeter un DISTINCT là-dedans, et vous plus que probablement aller en arrière en termes d'optimisation.

Je ne retournerai jamais dans une sous-requête comme ça. Une jointure serait beaucoup plus rapide.

select a.*
from a 
join b on a.id = b.id

Bien sûr, ne pas utiliser select * soit (surtout jamais l'utiliser lorsque vous faites une jointure au moins un champ est répété) et gaspille les ressources du réseau pour envoyer des données unnneeded.

Avez-vous examiné le plan d'exécution?

Qu'en est-

select a.* 
from a 
inner join b
on a.id = b.id

sans doute les champs d'identification sont les clés primaires?

Select a.* from a
inner join (Select distinct id from b) c
on a.ID = c.AssetID

J'ai essayé les 3 versions et ils ont couru sur le même. Le plan d'exécution était le même (jointure interne, IN (avec et sans clause where sous-requête), Exists)

Puisque vous ne choisissez pas les autres champs de B, je préfère utiliser le cas IN (Choisir ...) Tout le monde se pencherait sur la question et de savoir ce que vous essayez de faire (montrer seulement dans un si b. ).

votre problème est plus probable dans les sept tables dans « un »

faire la table FROM contiennent le "a.id" faire la prochaine jointure: jointure interne b sur a.id = b.id

puis se joindre aux six autres tables.

vous avez vraiment besoin de montrer toute la requête, la liste de tous les index, et le nombre de lignes approximatives de chaque table si vous voulez de l'aide réelle

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