Ruby 请助一个关于 mysql 的大数据查询语句优化.

lb563 · 2013年08月25日 · 最后由 kenshin54 回复于 2013年08月25日 · 2856 次阅读

从第一张表中查询出特定时间段登录的用户 id 的数据:

relation1 = self.select("accountid,characterid").where(:timestamp => day.beginning_of_day..day.end_of_day, :action => BehaviorType::CHAR_CREATE).group(:accountid)

从另外一表中查询存在第一张表中的用户 id 数据:

charids = relation1.all.map { |e| e.accountid }.uniq
relation2=self.select("accountid,characterid,level").where('accountid in (?)', charids)

最后取出relation2的总数。

自己测试了一下。能达到我的需求.但是 debug 进去看 sql 语句的时间发现有点丑陋

SELECT accountid,characterid,level FROM `log_login_or_logout` WHERE `log_login_or_logout`.`login_logout` = 0 AND (` ') AND (accountid in (1,3,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,84,..................)) GROUP BY accountid ORDER BY level desc

注意accountid in ..................... 这个里面被填満了用户 id

这样我有几点疑问:

1.如果 id 足够多的话会不会影响执行的效率。

2.还有没有更好的写法。尝试 google 没有找到理好的 (也许是我的搜索 keyword 不正确)

bug: mysql 小白,activerecrod 用过一些简单的常用的方法。更复杂的用法接触的不多。

Model 应该是类,要大写吧?

问题一,id 列表写死在 SQL 中多少会影响执行效率

问题二,如果是 SQL 的话,可以这样写:

SELECT accountid, MAX(characterid), level
  FROM model
 WHERE action = BehaviorType::CHAR_CREATE
   AND timestamp between DAY_BEGIN and DAY_END
 GROUP BY accountid, level
 ORDER BY level DESC

至于 active_record 写法,我的感觉是即使精通 SQL,有时候也是有点难写的。。

#1 楼 @ericguo 是的 model 应该大写。我还是用 self 来替代。

用 Arel 写 exists 子查询代替 in

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