微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

mysql – rails中的查询速度非常慢

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

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

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

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

解决方法:

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

>查询1 Mya(1个查询)

>为Mya查询10个Mybs(1个查询)

>为每个Myb查询5000 Mycs(10个查询)

>查询所有(4)Myc的每个Myc(10 * 5000查询)
>查询每个Myc的所有(4)Myd(10 * 5000个查询)

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

您可以通过告诉ActiveRecord在第一个查询中使用includes方法包含嵌套的Mybs Mycs和Myd来防止这种情况.这样,您只会执行一个大型查询,而ActiveRecord只会一次与数据库通信.

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐