359 votes

Rails :inclure vs :joint

Ce n'est plus un "pourquoi les choses fonctionnent de cette façon" question plutôt que d'un "je ne sais pas comment faire"...

L'évangile à tirer sur les dossiers que vous savez que vous allez utiliser est d'utiliser :include parce que vous obtiendrez une jointure et d'éviter tout un tas de requêtes supplémentaires:

Post.all(:include => :comments)

Toutefois, lorsque vous regardez les journaux, il n'y a pas de jointure qui se passe:

Post Load (3.7ms)   SELECT * FROM "posts"
Comment Load (0.2ms)   SELECT "comments.*" FROM "comments" 
                       WHERE ("comments".post_id IN (1,2,3,4)) 
                       ORDER BY created_at asc) 

C' est en prenant un raccourci, car il rassemble tous les commentaires à la fois, mais il n'est pas encore une jointure (qui est ce que l'ensemble de la documentation semble dire). La seule façon que je peux obtenir une jointure est d'utiliser :joins au lieu de :include:

Post.all(:joins => :comments)

Et les journaux:

Post Load (6.0ms)  SELECT "posts".* FROM "posts" 
                   INNER JOIN "comments" ON "posts".id = "comments".post_id

Ai-je raté quelque chose? J'ai une application avec une demi-douzaine d'associations et sur un écran, je l'affichage des données de tous. Me semble qu'il serait mieux d'avoir un rejoignez-ed requête au lieu de 6 personnes. Je sais que la performance sage, il n'est pas toujours mieux de faire une jointure plutôt que de requêtes individuelles (en fait, si vous allez par le temps passé, il semble que deux requêtes individuelles ci-dessus sont plus rapides que la jointure), mais après tous les docs que j'ai lu, je suis surpris de voir :include ne fonctionne pas comme annoncé.

Peut-être que Rails est conscient du problème de performances et de ne pas participer, sauf dans certains cas?

181voto

Greg Campbell Points 10321

Il semble que l' :inclure la fonctionnalité a été modifiée avec des Rails 2.1. Rails permettant de faire la liaison dans tous les cas, mais pour des raisons de performances, il a été changé à l'utilisation de plusieurs requêtes dans certaines circonstances. Ce billet de blog par Fabio Akita a quelques bonnes informations sur le changement (voir la section intitulée "Optimisé Désireux de Chargement").

106voto

prem Points 1499

.joins sera juste joint les tables et apporte les champs sélectionnés en retour. si vous appelez des associations sur les jointures du résultat de la requête, il va déclencher des requêtes de base de données à nouveau

:include seront désireux de charge inclus, les associations et les ajouter dans la mémoire. :include des charges de tous les tableaux d'attributs. Si vous appelez des associations, notamment du résultat de la requête, il ne sera pas le feu des questions

77voto

holden Points 5603

La différence entre les jointures et comprennent que l'utilisation de l'instruction include génère beaucoup plus de requêtes SQL de chargement dans la mémoire de tous les attributs de l'autre table(s).

Par exemple, si vous avez une table avec plein de commentaires et que vous utilisez un :joint => les utilisateurs à tirer dans toutes les informations de l'utilisateur à des fins de tri, etc il fonctionne parfaitement et prend moins de temps que :comprendre, mais dire que vous souhaitez afficher le commentaire avec le nom des utilisateurs, e-mails, etc. Pour obtenir de l'information à l'aide de :soudure, il faudra créer des requêtes SQL pour chaque utilisateur, il récupère, alors que si vous avez utilisé :inclure cette information est prêt à l'emploi.

Excellent exemple:

http://railscasts.com/episodes/181-include-vs-joins

55voto

Brian Maltzan Points 1051

En plus d'un des facteurs de performance, il y a une différence fonctionnelle. Lorsque vous rejoignez les commentaires, vous vous demandez quels sont les postes qui ont des commentaires - une jointure interne par défaut. Lorsque vous incluez des commentaires, vous demandez à tous les postes - une jointure externe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X