情景是这样的,我们的app接了app flyer 统计。用户的每个行为 都会给app flyer上报,产生大量的数据。我们通过app flyer提供的push接口 以天为频次 来获取这些统计数据 进行分析,这是背景。
这里遇到了几个问题
1.push过来的数据体是json格式 server端那边负责给我把它们存下来,我需要从这里面查
node下orm操作库sequelize如何查询json呢?
let _datas = await ModelDefines.Flyer.findAll({
attributes: [
[sequelize.json('data.platform'), 'platform'],
[sequelize.json('data.country_code'), 'country_code'],
[sequelize.json('data.agency'), 'agency']
],
where: Object.assign(_whereConditions, _transToMillisecond(_whereCreateTime))
}, true)
// 等价于
SELECT
`data`->>'$.platform' AS `platform`,
`data`->>'$.country_code' AS `country_code`,
`data`->>'$.agency' AS `agency`
FROM `adbus_flyer_data` AS `adbus_flyer_data`
WHERE (`adbus_flyer_data`.`data`->>'$.event_type') = 'install'
AND (`adbus_flyer_data`.`data`->>'$.platform') = 'ios'
AND (`adbus_flyer_data`.`data`->>'$.country_code') = 'TH'
AND (`adbus_flyer_data`.`create_time` < 1509292800000
AND `adbus_flyer_data`.`create_time` > 1509206400000);
2.之前做的比上面的low 之前还用到了分组查询 导致效率很低 通过请教DBA
写SQL ,能不分组就不分组,能不排序就不排序, 分组排序去重复比较吃资源
3.好吧 我把语句改成上面代码那样 我查出来之后自己分组加和统计。但还是巨慢。又请教了DBA
你的表有id , json_text ,create_time, 你在create_time 上建立索引, 然后用create_time 卡出来
这里有个细节就是我之前where条件里几个字段都是在json_text里的 如果用它们去查,做个explain会发现 mysql 要扫全表。
敲黑板:即使是将json里的字段提炼出来做虚拟列 再做索引 DBA也是不建议的。
所以我要把最上面的程序再改一下,去掉json字段的where 只用加了索引的create_time去卡数据。通过程序去where。
今天把代码重新写了下,筛选部分从db-where 改为program-where 并且建立了索引。
终于!线上的库 可以正常查询了_
后记:还没结束,每天灌入的数据都在2个G左右,时间长了靠索引卡也不是办法。所以会在近期首先把划分不太规范的商业化表拆出来放到专属的DB服上,再对数据进行分表写入,分表查询。这个方案基本能cover住了。