Rails对数据库进行多次查询

时间:2013-11-18 02:20:43

标签: sql ruby-on-rails ruby

我的用例很简单,我希望在我的网站页脚中有4列,每列中都有一个类别列表。

这是我的代码 - 它正在做我想要它做的事情,但是我注意到它正在对数据库进行4次调用,而它应该只执行一次来加载初始的Category集合。

- 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

终端输出:

(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

有什么建议吗?

1 个答案:

答案 0 :(得分:3)

在您实际使用recrod之前,ActiveRecord不会查询数据库,因此在这种情况下categories包含执行查询所需的信息,但不包含结果本身。您添加到categories偏移量并在实际使用之前将查询限制三次,因此它仅使用偏移量和有限查询,因此需要进行三次调用。如果您只想随叫随到,可以这样做:

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

然后代替

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

for category in categories.shift(perColumn)

请注意,shift会从数组中删除第一个N = perColumn元素并返回它们,因此您以后无法使用类别。

我的诚实意见是,您的数据库软件将能够比您的ruby代码更快地计算此结果。您过早地进行了优化,而这4个db查询并不重要。