se non erro: joins
ha prestazioni migliori rispetto includes
perché a livello di database:uso ActiveRecord si unisce per le prestazioni, ma caricare tutti i record associati nella memoria come con include
joins
provoca uninner join
includes
cause unsubquery
E, in generale, un inner join
è più veloce di un subquery
.
Esempio:
#app/models/owner.rb
class Owner < ActiveRecord::Base
has_many :pets
end
#app/models/pet.rb
class Pet < ActiveRecord::Base
belongs_to :owner
end
Utilizzando 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)
E ora utilizzando joins
che causa un 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"
così sembrerebbe come sarebbe essere quasi sempre meglio l'uso joins
su includes
perché:
includes
provoca una (la dichiarazioneIN
)subquery
joins
causa uninner join
che di solito è più veloce di un sottoquery
Tuttavia, v'è una Gotcha con l'utilizzo di joins
. This article does a great job describing it. Fondamentalmente, includes
carica tutti gli oggetti associati in memoria, in modo che se si esegue una query per uno qualsiasi degli attributi per tali oggetti associati, questo non colpisce il database. Nel frattempo, joins
NON carica in memoria gli attributi degli oggetti associati, quindi se si esegue una query per uno qualsiasi degli attributi, effettua ulteriori hit sul database.
Quindi, ecco la mia domanda: è possibile eseguire join interni come con joins
per prestazioni ma allo stesso tempo caricare tutti gli oggetti associati in memoria come fa includes
?
In un altro modo: è possibile caricare tutti gli oggetti associati in memoria come fa includes
, ma provoca un inner join in contrapposizione a un subquery?