rails中的查询速度非常慢

时间:2015-01-18 06:58:22

标签: mysql ruby-on-rails ruby

我想进行查询,但查询速度很慢,我有五个这样的模型:

class Mya < ActiveRecord::Base
    has_many :mybs
end

class Myd < ActiveRecord::Base
    belongs_to :myc
end

class Myc < ActiveRecord::Base
    belongs_to :myb
    has_many :myds
    has_many :myes
end

class Myd < ActiveRecord::Base
    belongs_to :myc
end

class Mye < ActiveRecord::Base
    belongs_to :myc
end

,我将一些测试数据插入mysql :(种子)

mya=Mya.create!(title: 'first test')
i=0
10.times{
    i=i+1
    myb=Myb.create!(title: "my_#{i}")
    5000.times{
        myc=Myc.create!(mya_id: mya.id, myb_id: myb.id)
        4.times {
            myd=Myd.create!(mya_id: mya.id, myb_id: myb.id, myc_id: myc.id)
            mye=Mye.create!(mya_id: mya.id, myb_id: myb.id, myc_id: myc.id)
        }
    }
}

在我的控制器中,我喜欢这样:

 def index
    @ms = Mya.first.to_json(:include => [{
                                              mybs: {
                                                  :include => {
                                                        :mycs => {
                                                            :include => [:myds, :myes]
                                                        }
                                                  }
                                              }
                                          }
                             ])
    render json:  @ms
  end

enter image description here

非常慢,帮助我,谢谢。抱歉我的英语。

github:https://github.com/scottxu/mytest

1 个答案:

答案 0 :(得分:5)

您正在运行双嵌套n + 1查询。那意味着你

  • 查询1 Mya(1个查询)
    • 查询Myb的{​​{1}}(1个查询)
      • 查询5000 Mya每个 Myc(10个查询)
        • 查询每个 Myb的所有(4)Myc(10 * 5000个查询)
        • 查询每个 Myc的所有(4)Myd(10 * 5000个查询)

这意味着您正在运行1 + 1 + 10 +(10 * 5,000)+(10 * 5,000)= 100,012个查询。由于每个查询都有一些开销,因为它需要向数据库发送数据和从数据库接收数据,因此控制器操作变得非常慢。

您可以通过告诉ActiveRecord在第一个查询中使用includes方法包含嵌套的Myc s MybMyc来阻止这种情况发生。这样,您将只执行一个大型查询,ActiveRecord将只与该数据库进行一次通信。

Myd