为什么Rails运行额外的不必要的查询?

时间:2017-02-28 15:23:17

标签: ruby-on-rails activerecord rails-activerecord ruby-on-rails-5

我有以下Rails代码,其中技术上最多执行两个查询,但由于某种原因,控制台显示三个不同的查询,如下面的屏幕截图所示。我的问题是为什么它在没有必要的情况下运行SELECT "pages".* FROM "pages"查询?

查询

    page = Page.includes(:page_roles)
    page.where(is_deleted: false).index_by(&:name)
    page_results = {}
    page.each do |entry|
        result_entry = entry.as_json;
        result_entry['page_roles'] = entry.page_roles
        page_results[entry.name] = result_entry
    end

控制台输出

Page Load (0.0ms)  SELECT "pages".* FROM "pages" WHERE "pages"."is_deleted" = $1  [["is_deleted", false]]
PageRole Load (0.5ms)  SELECT "page_roles".* FROM "page_roles" WHERE "page_roles"."page_id" IN (1, 2, 3, 4)
Page Load (0.5ms)  SELECT "pages".* FROM "pages"
CACHE (0.0ms)  SELECT "page_roles".* FROM "page_roles" WHERE "page_roles"."page_id" IN (1, 2, 3, 4)
Completed 200 OK in 117ms (Views: 16.9ms | ActiveRecord: 17.0ms)

Screenshot of the console

3 个答案:

答案 0 :(得分:1)

那是因为第一次任务。你可以通过这样做来缩短所有这些:

.../Libraries/

答案 1 :(得分:1)

这就是原因:

page = Page.includes(:page_roles)
page.where(is_deleted: false).index_by(&:name) # your first two queries (pages + page_roles). 
                                               # query is triggered by index_by (method of enumerable, not activerecord) and result is ignored
                                               # as it's not saved anywhere.

page_results = {}
page.each do |entry| # your second two queries. Note that this one doesn't use `is_deleted: false` filter.
                     # page_roles query is served from cache as it didn't change.
    result_entry = entry.as_json;
    result_entry['page_roles'] = entry.page_roles
    page_results[entry.name] = result_entry
end

答案 2 :(得分:0)

我相信这是因为你有page.where查询仍会使用Page表上的ActiveRecord查询接口而不使用存储为page的ActiveRecord集合。