新手问题 Ruby 高效 MySQL 数据库查找解决方法

xiaoxiao · 2013年09月03日 · 最后由 xiaoxiao 回复于 2013年09月03日 · 2994 次阅读

数据库里有很多数据,每条数据都有一个字段是时间(exercisetime),一个字段是值(value),现在前端需要得到是某一区间内所有的数据的值的和。

@data=[]
@totaldata=[]
@name=[]
Shgrade.all.each do |j|
  (1..7).each do |i|
    sum=0
    Shclass.where(:shgrade_id=>j.id).each do |z|
      z.users.each do |k|
        sum+=k.exercises.where("?<=exercisetime and exercisetime<=?", Time.new((Time.now+(i-7).day).strftime("%Y").to_i,  (Time.now+(i-7).day).strftime("%m").to_i, (Time.now+(i-7).day).strftime("%d").to_i), Time.new((Time.now+(i-7).day).strftime("%Y").to_i,  (Time.now+(i-7).day).strftime("%m").to_i, (Time.now+(i-7).day).strftime("%d").to_i,23,59,59)).sum(:value)
      end
    end
    @data<<sum
    sum=0
  end 
  @totaldata<<@data
  @data=[]      
end

Shgrade.all.each do |i|
  @name<<i.name
end

上面代码的主要功能是得出过去一周的所有数据的值得和。然后将结果放入到数组@totaldata中 但是我发现如果数据量很多的话,这样查找的话很费时,我导入的测试数据有一千条多条,测试时需要将近半分钟。。。 各位有什么经验可以分享的没。。。如何处理大数据

几千条要半分钟... explain 一下生成的 sql 看看吧,估计是 time 没有加 index

如何加,我 google 了一下 mysql 加索引好像是可以提高查找速度的

我的强迫症又犯了 为什么不用 bewteen... 然后 可以优化的地方就是Model.where(xxx).pluck(:value).sum() 这个结果就是你数据库里所有 value 的和了 为什么前面还有个sum+=呢~

源码贴出来了,这解释了 3 楼为什么要加 sum 的原因了。刚才没贴全

#5 楼 @xiaoxiao 直接这样写就行啊 k.exercises.where('exercisetime BETWEEN ? AND ?', i.days.ago.midnight, i.days.ago.midnight.tomorrow) 我没算你具体是要找哪天... 真心的... 不想看... 没排版太乱 哈哈哈~

是有点乱,我排版排版,呵呵

很奇怪的是我没保存之前是好好的,一保存就成这挫样了

我给加上代码块格式了,楼主自己编辑一下,缩进没处理好。

楼主在新手问题区已经是熟面孔了,竟然还没有学会格式化代码。

#7 楼 @xiaoxiao 有两点 你的时间不需要自己拼字符串的 直接用 Time 对象就行 自己算好了哪天零点到哪天零点 然后只 pluck 出你要的字段然后 sum 最后的 SQL 应该是个 sum(value) 这样的语句就对了... 你 1000 多的数据 得怎样才能到半分钟啊

谢谢站长,我还是新手

同时谢谢 zj0713001 的大力支持

#12 楼 @xiaoxiao 刚刚手误打错了 最后的 SQL 应该是个 sum(value) 这样的语句就对了 原回帖已改

@zj0713001 确实是这样的,要花半分钟的,总的数据量我说错了有一万多条,我改了也是这样的 sum+=k.exercises.where("exercisetime between ? and ?",0.days.ago.midnight+i.day-7.day, 0.days.ago.midnight.tomorrow+i.day-7.day).pluck(:step).sum()

我看了 log 记录,每条记录查找要 3ms,10000 条是要这么多的,

#11 楼 @xiaoxiao 新手不是不学习的借口,格式化提示一直放在编辑框的旁边,最近还加上了代码格式化按钮(图片上传按钮旁)。

@Rei rubychina 是越改越好了

#14 楼 @xiaoxiao 刚看清楚你上面是嵌套了两个循环... 这个逻辑能简化成一条语句吧 user group 出来

@zj0713001 group 没怎么用过,我记得在 railscast 上看到过这用法,我到网上找找

實時性要求不高的話,每個小時後臺算一次存起來,前臺直接調用就好

楼主请认真发帖,排好格式,不然下次不让你发帖了,你之前发的贴全都是乱七八糟的! 上 Ruby China 这么久了还不会用?Ruby China 的功能你好歹研究一下吧!

如何贴代码请看这贴:http://ruby-china.org/topics/13152

好的,站长

需要 登录 后方可回复, 如果你还没有账号请 注册新账号