简体   繁体   中英

Rails making multiple queries to the database

My use case is simple, I want to have 4 columns in the footer of my website with a list of categories in each column.

Here's my code - it's doing what I want it to do, however I have noticed it's making 4 calls to the database, when it should be doing only one to load the initial Category collection.

- categories = Category.order('name ASC')
- perColumn = (categories.size / 3).to_i

.row
  .col-md-3
    ul
      - for category in categories.limit(perColumn)
        li
          = link_to category.name, category

  .col-md-3
    ul
      - for category in categories.offset(perColumn).limit(perColumn)
        li
          = link_to category.name, category

  .col-md-3
    ul
      - for category in categories.offset(perColumn * 2).limit(perColumn)
        li
          = link_to category.name, category

  .col-md-3
    ul
      - for category in categories.offset(perColumn * 3).limit(perColumn)
        li
          = link_to category.name, category

Terminal output:

(0.1ms)  SELECT COUNT(*) FROM "categories"
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6 OFFSET 6
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6 OFFSET 12
  Category Load (0.2ms)  SELECT "categories".* FROM "categories" ORDER BY name ASC LIMIT 6 OFFSET 18

Any suggestions?

ActiveRecord does not query the database until you actually use the recrod, so in this case categories contains the information needed to execute your query but not the result itself. You add on to the categories offset and limit your query three times before you actually use it, so it only uses the offset and limited query, thus needing to make three calls. If you want to only make on call, you can do this:

categories = Category.order('name ASC').to_a

and then instead of

for category in categories.offset(perColumn * X).limit(perColumn)

With

for category in categories.shift(perColumn)

Note that shift removes the first N=perColumn elements from the array and returns them, so you wont be able to use categories later.

My honest opinion is that your database software will be able to compute this result much quicker than your ruby code. You are prematurely optimizing, and those 4 db queries don't really matter that much.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM