jdj_dk

jdj_dk

Ecto preload causing multiple SELECT queries

So I’m a bit confused and would really appreciate your help.

I have a query like this:

query = from(
       c in App.Card, 
       left_join: comments in assoc(c, :comments)
   )
App.Repo.get(query, 557)

It returns the card I’m looking for but with no comments preloaded. So I can’t access them even though I’ve joined the tables. So I go ahead and preload the comments

query = from(
       c in App.Card, 
       left_join: comments in assoc(c, :comments),
       preload: [:comments]
   )
App.Repo.get(query, 557)

And it now preloads and I can access the comments.

What worries me is the following:

The first query resulted in the following SQL:

[debug] QUERY OK source="cards" db=0.7ms
SELECT c0."id", c0."title", c0."description", c0."position", c0."board_column_id", c0."author_id", c0."inserted_at", c0."updated_at" FROM "cards" AS c0 LEFT OUTER JOIN "card_comments" AS c1 ON c1."card_id" = c0."id" WHERE (c0."id" = $1) [5556] 

But the second one resulted in an additional SELECT statement

[debug] QUERY OK source="cards" db=0.9ms
SELECT c0."id", c0."title", c0."description", c0."position", c0."board_column_id", c0."author_id", c0."inserted_at", c0."updated_at" FROM "cards" AS c0 LEFT OUTER JOIN "card_comments" AS c1 ON c1."card_id" = c0."id" WHERE (c0."id" = $1) [556]
[debug] QUERY OK source="card_comments" db=0.5ms
SELECT c0."id", c0."content", c0."remote_id", c0."author_id", c0."card_id", c0."inserted_at", c0."updated_at", c0."card_id" FROM "card_comments" AS c0 WHERE (c0."card_id" = $1) ORDER BY c0."card_id" [556]

Is this expected behavior? Is this something I should be concerned about? Because this is just a small example from a larger query where I do multiple joins and preloads (resulting in many SELECT statements). It seems like there’s an N+1 problem here.

Another question is concerning the joins and preloads when having multiple comments. The query above will throw an error because it will return x number of rows where x is the number of comments associated with the card. This makes sense considering how join works but I would assume that Ecto would abstract that away? Or am I just to spoiled by Rails? :slight_smile: Perhaps I’m doing something very wrong here. Any help is much appreciated.

Thanks everyone :slight_smile:

Marked As Solved

belaustegui

belaustegui

I think that there is a little mistake in your query.

In your example you write:

query = from(
       c in App.Card, 
       left_join: comments in assoc(c, :comments),
       preload: [:comments]
   )
App.Repo.get(query, 557)

This is joining the comments table and pointing it in the comments variable. In the preload you should use this comments that you have already loaded. Try this:

query = from(
       c in App.Card, 
       left_join: comments in assoc(c, :comments),
       preload: [comments: comments]
   )
App.Repo.get(query, 557)

The Ecto docs contain more information about how to use preloads.

10
Post #2

Also Liked

jdj_dk

jdj_dk

@belaustegui You are awesome. Thank you so much. This actually cleared up my concerns. Have a great day :smile:

xingxing

xingxing

@jdj_dk Awesome question too, :grin:

Last Post!

xingxing

xingxing

@jdj_dk Awesome question too, :grin:

Where Next?

Popular in Questions Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

We're in Beta

About us Mission Statement