12
votes

Ce qui est plus rapide: rejoindre le groupe par ou une sous-requête?

Disons que nous avons deux tables: "voiture" et "partie", avec une table de jonction dans "car_parart". Dis que je veux voir toutes les voitures qui ont une partie 123 en eux. Je pourrais faire cela: xxx

ou je pourrais faire ce xxx

maintenant, tout en moi veut utiliser la première méthode parce que je " J'ai été élevé par de bons parents qui m'ont instillé une haine puritaine de sous-demandes et d'un amour de la théorie de la consigne, mais cela m'a été suggéré que ce gros groupe est pire qu'une sous-requête.

Je dois souligner que nous sommes sur SQL Server 2008. Je devrais également dire que, dans la réalité, je souhaite sélectionner basé sur l'ID de pièce, le type de pièce et éventuellement d'autres choses aussi. Donc, la requête que je veux faire ressemble réellement à ceci: xxx

ou ... xxx


3 commentaires

Avez-vous dirigé les deux? Regardé les plans de requête? Benchmarked il?


Je devrais générer une charge de données, donc je ne vais pas y arriver jusqu'à la semaine prochaine. Et quand j'ai googlé pour une réponse, je n'en ai pas trouvé un, alors ça vaut la peine d'avoir posté une question en ligne pour quelqu'un d'autre qui pourrait regarder.


Le groupe est intensif de main-d'œuvre, utilisé pour calculer des trucs comme des moyennes, des sommes, etc. Vous semblez l'utiliser pour éliminer les doublons. Essayez distinct sans le groupe par ...


3 Réponses :


4
votes

La meilleure chose à faire est de les tester vous-même, sur des volumes de données réalistes. Cela ne bénéficierait non seulement à cette requête, mais pour toutes les requêtes futures lorsque vous n'êtes pas sûr, quelle est la meilleure façon.

Les choses importantes à faire incluent:
- Test sur les volumes de données de niveau de production
- Test Assez et cohérent (Clear Cache: http://www.adathdev.co.uk/2010/02/would-you-Like-sql-cache-with-that.html )
- Vérifiez le plan d'exécution

Vous pouvez soit surveiller à l'aide du profileur SQL et vérifier la durée / les lectures / écrit / CPU là-bas, ou SET STATISTIQUES IO ON; Définissez le temps de statistiques sur; pour produire des statistiques sur SSMS. Comparez ensuite les statistiques de chaque requête.

Si vous ne pouvez pas faire ce type de test, vous vous exposez potentiellement à des problèmes de performance dans la ligne que vous devrez ensuite régler / rectifier. Vous pouvez utiliser des outils que vous pouvez utiliser qui générera des données pour vous.


0 commentaires

3
votes

J'ai des données similaires, j'ai vérifié le plan d'exécution pour les deux styles de requête. À ma grande surprise, la colonne de sous-requête (CIS) a produit un plan d'exécution avec 25% moins de frais d'E / S à la requête interne (IJ). Dans le plan d'exécution de la CEI, je reçois une analyse de 2 index de la table intermédiaire (CAR_PART) par rapport à une analyse de l'index de l'intermédiaire et une jointure de hachage relativement plus chère dans l'IJ. Mes index sont sains mais non regroupés, il s'agit donc de raisonner que les analyses d'index puissent être apportées un peu plus rapidement en les regroupant. Je doute que cela aurait une incidence sur le coût de la jointure de hachage qui constitue l'étape la plus coûteuse de la requête IJ.

Comme les autres ont souligné, cela dépend de vos données. Si vous travaillez avec de nombreux gigaoctets dans ces 3 tables, écartez-vous. Si vos lignes sont numérotées dans les centaines ou des milliers, vous risquez de diviser les poils sur un très petit gain de performance. Je dirais que la requête IJ est beaucoup plus lisible, donc aussi longtemps que cela suffit, Tout développeur futur qui touche votre code une faveur et leur donne quelque chose de plus facile à lire. Le nombre de lignes dans mes tables est de 188877, 283912, 13054 et les deux requêtes retournèrent en moins de temps qu'il a fallu pour siroter du café.

Petit PostScript: car vous n'agregistrez pas de valeurs numériques, on dirait que vous voulez choisir de sélectionner distinct. À moins que vous ne puissiez réellement faire quelque chose avec le groupe, il est plus facile de voir votre intention de sélectionner plutôt que du groupe à la fin. Io coût est le même mais on indique votre intention mieux IMHO.


0 commentaires

2
votes

avec SQL Server 2008, je m'attendrais à ce que dans code> soit plus rapide car il est équivalent à cela.

SELECT Car.Col1, Car.Col2, Car.Col3 
FROM Car
WHERE EXISTS(SELECT * FROM Car_Part
            WHERE Car_Part.Car_Id = Car.Car_Id
            AND Car_Part.Part_Id = @part_to_look_for
)


0 commentaires