共计 2203 个字符,预计需要花费 6 分钟才能阅读完成。
【case 1】
我的项目背景:
须要返回一些 GC 的统计数据。相干数据存在 frame 这张表内,表中的数据一行就是一帧的数据,能够了解为记录了这一帧内的性能信息。与需要相干的 col 是 GcChartSample,是一个 json 类型的数据,外面存的是该帧触发的各个品种的 GC 的大小,没有触发的 GC 的字段将不会列在这个 GC 中。例如:{“Internal”:252,”Other”:192,”Scripts”:7832},就是 InternalGC 是 252 字节,OtherGC 是 192 字节,ScriptsGC 是 7832 字节。
求:各类 GC 的无效帧均值(即:非 0 帧的均值)和最大值
我的第一版解法:
将区间内的所有帧的 GcChartSample 字段取出放入 go 中,在 go 中进行解决。即:先开一个 gcLineMap 记录所有呈现过的 GC 品种,而后再依据 gcLineMap 建设 gcItemArray,分类 push 非 0 的 GC 值,最初依据各个数组算出统计数据。
弱化局部需要后,mentor 举荐的解法:
用户在查看性能报告的时候,通常只会关注局部 GC 的值,例如:ScriptsGC,RenderingGC 等。因而,并不一定要求出所有 GC 的统计。并且 sql 善于做统计的操作。将统计的工作放在 sql 里做,可能缩小 IO。
因而,sql 批改如下:
select sum(cast(GcChartSample ->> 'Scripts' as Integer)) as ScriptsGCMax, round(count(cast(GcChartSample ->> 'Scripts' as Integer)), 2) as ScriptsGCMean, | |
max(cast(GcChartSample ->> 'Rendering' as Integer)) as RenderingGCMax, round(avg(cast(GcChartSample ->> 'Rendering' as Integer)), 2) as RenderingGCMean, | |
max(cast(GcChartSample ->> 'GUI' as Integer)) as GUIGCMax, round(avg(cast(GcChartSample ->> 'GUI' as Integer)), 2) as GUIGCMean, | |
max(cast(GcChartSample ->> 'Animation' as Integer)) as AnimationGCMax, round(avg(cast(GcChartSample ->> 'Animation' as Integer)), 2) as AnimationGCMean | |
from upa.frame where partitionkey = 5; |
起初放心,应用 sql 里的 avg 操作只能返回均值,无奈返回无效帧均值。然而,翻阅 sql 文档后发现,sum 会主动疏忽值为 null 的字段。
psql agg 操作总结如下:
AVG
SELECT AVG(amount)::numeric(10,2) FROM payment; //To make the output more readable | |
SELECT AVG(DISTINCT amount)::numeric(10,2) FROM payment; //The following query returns the average payment made by customers. Because we use DISTINCT, PostgreSQL only takes unique amounts and calculates the average. |
COUNT
将列名作为参数,失去 NULL 之外的数据行数 | |
将星号作为参数,失去所有数据的行数 (蕴含 NULL)。 |
SUM
对于列外面数据有 NULL 的,也是会当时去掉 NULL 再计算。
【case 2】
翻阅组内我的项目的时候发现,psql 中含有 array_agg 操作的,通常都不会在 go 端做解决,而是以 string 的形式接管,传递给前端解析成 json 进行操作。
学习笔记:
PostgreSQL array_agg() 函数是一个聚合函数,它返回一个蕴含了一个分组中的所有的值的组成的数组。
【case 3】
我的项目背景:
在做一个需要的时候,我将一个某个 sql 的返回值用 string 接到后,进行了 Unmarshal 操作,mentor 提醒说最好寻找一下优化的办法,因为 Unmarshal 操作要一个一个的对,比拟伤性能。
学习笔记:
- Unmarshal 将 json 字符串解码到相应的数据结构。
- json 字符串解析时,须要一个“接管体”承受解析后的数据,且 Unmarshal 时接管体必须传递指针。
- 解析时,接管体可自行定义。json 串中的 key 主动在接管体中寻找匹配的项进行赋值。
- 匹配规定:先查找与 key 一样的 json 标签,找到则赋值给该标签对应的变量;没有 json 标签的,就从上往下顺次查找变量名与 key 一样的变量,或者变量名疏忽大小写后与 key 一样的变量,第一个匹配的就赋值,前面就算有匹配的也疏忽(变量可导出,首字母大写)。
- 当接管体中存在 json 串中匹配不了的项时,解析会主动疏忽该项,该项仍保留原值。
- json 解析后,json 串中 value,只有是 ” 简略数据 ”,都会依照默认的类型赋值。
- 简略数据:是指不能再进行二次 json 解析的数据,例如 name
- 复合数据:是可进行二次甚至屡次 json 解析的,因为它的 value 也是个可被解析的独立 json