分类: Java
2009-05-08 18:43:13
Rendering projects/index
SQL (0.3ms) SELECT count(*) AS count_all FROM "tasks" WHERE ("tasks".project_id = 61)
SQL (0.2ms) SELECT count(*) AS count_all FROM "tasks" WHERE ("tasks".project_id = 62)
SQL (0.3ms) SELECT count(*) AS count_all FROM "tasks" WHERE ("tasks".project_id = 63)
SQL (0.2ms) SELECT count(*) AS count_all FROM "tasks" WHERE ("tasks".project_id = 64)
可以看到sql执行了很多次,我们应该如何降低数据库查询的次数呢?
@projects = Project.find(:all, :include => :tasks)
这样的确降低了查询次数,但是还有一点不足,就是我们只需要count,并不需要所有的字段。
Instead of the eager loading we’re going to use a counter cache column.
我们要创建一个migration,给project添加一个新的字段called, tasks_count. defaut=> 0
def AddTasksCount < ActiveRecord::Migration
def self.up
add_column :projects, :tasks_count, :integer, :default => 0
Project.reset_column_information
Project.all.each |p|
p.update_attribut :tasks_count, p.tasks.length
end
end
def self.down
remove_column :projects, :tasks_count
end
end
The name we’ve given our new column is important. It needs to be the name of the model we want to count, followed by _count
.
The default value is important too. If it is not zero then the count
won’t work correctly. After we’ve created our new column we need to set
the value of the count column in each current project. To do this we
loop through each project and set its tasks_count
attribute to the number of tasks the project has. We use length
rather than size
to get the number of tasks as size
would use the counter cache column. which would have its default value of zero.
As we’re modifying a Project
in the same migration in
which we add a column to it there’s a possibility that the column
information may be cached. It’s a good practice to make sure that it’s
reset and we do this with Project.reset_column_information
.