Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Leveraging N+1 queries

Leveraging N+1 queries

Lightning talk based a blog post written by Piao Qihuan at https://sourcediving.com/speed-up-your-performance-with-n-1-dont-kill-it-82fe3444e7d#.fuxyy4epn.

Presented at: RubyConf Portugal 2016

Sebastian Sogamoso

October 27, 2016
Tweet

More Decks by Sebastian Sogamoso

Other Decks in Programming

Transcript

  1. # recipes/index.html.erb <ul> <%= render @recipes %> </ul> # recipes/_recipe.html.erb

    <li> Title: <%= recipe.title %> <!-- here's the N+1 query --> Author: <%= recipe.user.name % </li>
  2. Queries will look like this when visiting recipes#index SELECT `recipes`.*

    FROM `recipes` WHERE ... SELECT `users`.* FROM `users` WHERE `users`.`id` = 1111 LIMIT 1 SELECT `users`.* FROM `users` WHERE `users`.`id` = 1112 LIMIT 1 SELECT `users`.* FROM `users` WHERE `users`.`id` = 1113 LIMIT 1 SELECT `users`.* FROM `users` WHERE `users`.`id` = 1114 LIMIT 1
  3. Log will now look like this SELECT `recipes`.* FROM `recipes`

    WHERE ... SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1111, 1112, 1113, 1114)
  4. # recipes/_recipe.html.erb <% cache recipe do %> <li> Title: <%=

    recipe.title %> Author: <%= recipe.user.name %> </li> <% end %>
  5. On first recipes#index visit Cache digest for app/views/recipes/index.html.erb: f632c9956497563f2a7b2ed0483ab9de Read

    fragment views/recipes/864277-20160728164012000000000/ f632c9956497563f2a7b2ed0483ab9de (1.7ms) Write fragment views/recipes/864277-20160728164012000000000/ f632c9956497563f2a7b2ed0483ab9de (1.2ms) ...
  6. On subsequent visits, it should read from cache Cache digest

    for app/views/recipes/index.html.erb: f632c9956497563f2a7b2ed0483ab9de Read fragment views/recipes/864277-20160728164012000000000/ f632c9956497563f2a7b2ed0483ab9de (0.3ms) ...
  7. Eager loading users will be unnecessary and in fact have

    a detrimental effect def index - @recipes = Recipe.published.includes(:user) + @recipes = Recipe.published end
  8. We will now only fire one query for the page!

    SELECT `recipes`.* FROM `recipes` WHERE ...