环境:Ruby 2.0.0,Rails 4.0.3,Windows 8.1,PostreSQL,Datatable 1.12.2,Will_Paginate 3.0.5,所有这些都在运行服务器和客户端的开发高端笔记本电脑上。请注意,原始问题已被删除并替换为此问题,以直接解决问题的原因。
当我对数据库进行种子设定以模拟满载时,我的应用程序的索引操作存在性能问题。问题似乎是它读取整个模型数据库,然后它读取显示索引所需的记录。
控制器代码导致此问题。在这种情况下,它与Railscast 340不同。我添加了导致问题的行,因为没有它我遇到了错误。显然,这个补丁是错误的。控制器代码实际上在respond_to之前发出记录集的读取。这未在Railscast 340中显示,但显示在respond_to documentation中。没有它,我在视图中收到错误。控制器代码是:
def index
@products = Product.all # This line seems to be the problem, but errors occur without it.
respond_to do |format|
format.html
format.json { render json: ProductsDatatable.new(view_context) }
end
end
当@products = Product.all不在控制器索引操作中时,为每个nil接收nomethoderror的视图段是:
<% @products.each do |product| %>
在样品运行中,如下所示,第一个序列需要大约3.4秒,第二个序列大约需要0.1秒。此示例仅在我的开发系统上,这是一台运行服务器和客户端的高端笔记本电脑。但是,我非常担心这种设计即使在分发到生产中也不会扩展。
第一次阅读和完成是:
SELECT "products".* FROM "products" WHERE "products"."company_id" = 54
…
Completed 200 OK in 3393ms (Views: 2851.6ms | ActiveRecord: 418.3ms)
以下阅读和完成是:
SELECT "products".* FROM "products" WHERE "products"."company_id" = 54 ORDER BY stock_number asc LIMIT 10 OFFSET 0
…
Completed 200 OK in 103ms (Views: 71.0ms | ActiveRecord: 26.0ms)
编辑以添加Explain Analyze
有趣的区别在于第一个查询没有显示索引,但架构说产品是由公司索引的?
首先查询:
"Seq Scan on products (cost=0.00..12.65 rows=234 width=51) (actual time=0.036..0.114 rows=234 loops=1)"
" Filter: (company_id = 54)"
" Rows Removed by Filter: 218"
"Total runtime: 0.153 ms"
第二次查询:
"Limit (cost=0.27..6.76 rows=10 width=51) (actual time=0.015..0.036 rows=10 loops=1)"
" -> Index Scan using index_products_on_stock_number on products (cost=0.27..152.07 rows=234 width=51) (actual time=0.014..0.033 rows=10 loops=1)"
" Filter: (company_id = 54)"
" Rows Removed by Filter: 14"
"Total runtime: 0.063 ms"
答案 0 :(得分:1)
如果你查看railscasts.com/episodes/340-datatables上的代码来归档views/products/index.html.erb
,你会看到他删除了表格中的tbody主体。您的问题是,在第一次加载页面时,您尝试加载并将数据库中的所有记录包含在视图中。