再谈Bullet

曾几何时,开发环境中突如其来的Bullet(以下简称bt)搞得我措手不及,无尽的弹框弄得人心烦意乱;曾几何时,不明白什么N+1 Query的我,对着弹框里的提示信息,无脑地到处乱加includes。。。

时过境迁。。。好吧,我不文艺了,讲主题吧!

前两天想抽出点时间对快轮系统的性能进行一些优化,首先想到的就是bt这个gem,由于该项目还未配置过bt,因此尝试着安装一下

1.安装

在gemfile的开发组中加入了bt

group :development do
  gem "bullet"
end

然后bundle了一下,重启服务,发现并没有什么X用。。。

2.配置

于是赶紧在github里查了一下,原来是需要在 config/environments/development中配置的

if defined?(Bullet)  
  config.after_initialize do
    Bullet.enable = true
    Bullet.alert = true
    Bullet.bullet_logger = true
    Bullet.console = true
    Bullet.growl = false
    # Bullet.xmpp = { :account  => 'bullets_account@jabber.org',    
    #                 :password => 'bullets_password_for_jabber',    
    #                 :receiver => 'your_account@jabber.org',    
    #                 :show_online_status => true }    Bullet.rails_logger = true    
    # Bullet.honeybadger = true    # Bullet.bugsnag = true    
    # Bullet.airbrake = true    # Bullet.rollbar = true    Bullet.add_footer = true    
    # Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]    
    # Bullet.slack = { webhook_url: 'http://some.slack.url', foo: 'bar' }    
  end
end

需要增加一个是否安装bt的判断,然后配置信息中,首先需要enable,然后alert就是弹框提示,bullte_logger就是在log中也显示提示信息;

此时再重启一下服务,果然熟悉的弹框出现了!

3.多重includes

解决普通的N+1 Query大家已经比较熟悉了,此处也不多赘述。有时候会出现includes之后,依然提示还是N+1的情况,仔细分析一下,原来被includes的对象,还会继续调用与自己关联的其他模型,此时就需要多重includes。解决思路有了,剩下的其实也就是个写法问题:

# 比如在‘任务动态’页面,每个event都需要调用对应的eventable(因为是多态关联,其实就是task或者subtask)
# 并且还会调用操作人(operator)的信息,比如username
# 此时如果仅仅includes这两个,还是会继续提示N+1 Query
Fg::Event.includes([:eventable, :operator])
# 原来是因为任务动态页面还会显示操作人的头像,而头像的链接不是存在users表中,而是存在employees表中,两张表是一对一的关系,这时就需要多重includes了:
Fg::Event.includes([:eventable, :operator => [:employee]])
# 理论上可以includs无数层,有一点需要注意,需要重复includes应该写在后面,不然会报错,比如:
Fg::Event.includes([:operator => [:employee], :eventable])
4.Counter Cache

当出现这个提示的时候,我又懵了。。。
然后在railscast找了个视频教程,其中正好有说明这个问题的内容。
举个例子:

# 有一张provinces表,和一张cities表,显然,一个province has_many cities
# 然后我在一个页面,列出所有的province的名称,并且在名称后面显示每个province具有的city数量:province_a.cities.count
# 此时刷新一下页面,就跳出提示说counter_cache了
# 解决方案如下:
# 1.给provinces表加一个cities_count的字段,整数型,默认值是0,执行迁移;
# 2.在cities表申明belongs_to province的地方,多加上一句话:
    belongs_to :province, counter_cache: true
# 3.在需要调用的地方,直接调用 province_a.cities_count

# 其实这么申明之后,本质就是,当cities表的数据有添加或者删除时,会自动找到对应的province,然后更新其cities_count字段(加一或者减一)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 11,711评论 0 17
  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 10,219评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,898评论 18 399
  • 一、实验目的 学习使用 weka 中的常用分类器,完成数据分类任务。 二、实验内容 了解 weka 中 explo...
    yigoh阅读 12,751评论 5 4
  • Naive: 这题真的是Hard Level。。。 Better: 枚举高度。把每一种高度的Largest rec...
    98Future阅读 1,209评论 0 0