wenn ich nicht irre: joins
bessere Leistung als includes
weil auf Datenbankebene hat:Active Einsatz für die Leistung verbindet aber alle zugehörigen Datensätze in den Speicher geladen werden, wie mit umfasst
joins
verursacht eineinner join
includes
Ursachen einsubquery
Und in der Regel ist ein inner join
schneller als ein subquery
.
Beispiel:
#app/models/owner.rb
class Owner < ActiveRecord::Base
has_many :pets
end
#app/models/pet.rb
class Pet < ActiveRecord::Base
belongs_to :owner
end
Mit rails console
:
# showing how 'includes' in rails causes an IN statement which is a subquery
irb(main):001:0> @owners = Owner.all.includes(:pets)
Owner Load (2.7ms) SELECT "owners".* FROM "owners"
Pet Load (0.4ms) SELECT "pets".* FROM "pets" WHERE "pets"."owner_id" IN (1, 2, 3)
Und jetzt mit joins
was bewirkt, dass ein inner join
:
irb(main):001:0> @owners = Owner.all.joins(:pets)
Owner Load (0.3ms) SELECT "owners".* FROM "owners" INNER JOIN "pets" ON "pets"."owner_id" = "owners"."id"
So würde es scheinen, wie es fast immer besser wäre, die Verwendung joins
über includes
weil:
includes
einesubquery
(dieIN
Anweisung) verursachtjoins
verursacht eineinner join
, die als eine Unterabfrage in der Regel schneller ist
Allerdings gibt es ein gotcha mit joins
verwenden. This article does a great job describing it. Im Grunde lädt includes
alle zugeordneten Objekte in den Speicher, so dass, wenn Sie für eines der Attribute für diese zugeordneten Objekte abfragen, es nicht die Datenbank trifft. In der Zwischenzeit lädt joins
die Attribute der zugeordneten Objekte NICHT in den Speicher. Wenn Sie also nach einem der Attribute suchen, werden zusätzliche Treffer in der Datenbank ausgeführt.
Also hier ist meine Frage: Ist es möglich, innere Joins wie mit joins
für die Leistung zu tun, aber gleichzeitig alle damit verbundenen Objekte in den Speicher wie includes
10 laden?
Anders ausgedrückt: Ist es möglich, alle zugehörigen Objekte in den Speicher zu laden, wie includes
tut, aber verursacht eine innere Verknüpfung im Gegensatz zu einer Unterabfrage?