如何简单快捷的查询性能数据 - Perfetto中SQL语句

说实话,第一次使用Perfetto的SQL查询功能时,我对它的简单和直接感到惊讶。
想想看,过去你必须在不同的工具之间来回切换来分析性能数据。
现在打开Perfetto可视化网页(https://ui.perfetto.dev/),将捕获的跟踪文件放入其中,加载后单击侧栏中的“查询(SQL)”选项。
整个操作过程比点外卖还要顺畅。

以基本搜索为例。
上次排查WebView加载缓慢的问题时,我直接使用SQL语句“select Major,ts,name from slice”,在几分钟内捕获了所有事件的持续时间、时间戳和名称。
说实话,这种即时反馈的感觉让人很安心。
特别是,使用 select (dur/1 e6 ) as '耗时(秒)' 将微秒单位转换为秒后,数据读取起来变得更加直观——后来我在分析游戏帧率抖动问题时再次使用了这个技巧,效果立竿见影。

有趣的部分是条件查询部分。
我有一个客户,他的程序崩溃总是与特定线程相关。
当时,我使用直接从光盘中选择(dur/1 e6 ),其中名称如“%doTraversals%”来锁定问题线程。
这个模糊匹配功能真是太神奇了,尤其记得在搜索词前后加百分号,不然很容易漏掉。
后来我想如果我直接在dur desc内添加订单,把耗时最长的订单放在前面,效率可以进一步提高。

说到执行顺序,我不明白为什么我必须按照from→where→select的顺序,然后再尝试将where放在前面。
结果整个界面卡住了十多秒,结果才出来。
这让我意识到,先找到数据源,再过滤条件,最后提取字段的规则是不能打破的。
另一个特别方便的优化建议是直接在 select 中计算平均值然后输出,例如 select avg(dur/1 e6 ) from slice where name like '%still%',这样 Python 脚本在获取数据时就不必单独处理。

对于自动分析扩展,我运行了一个Python脚本。
我记得为游戏项目设置一个环境,使用 perfetto_trace_processor.load("path/to/trace.perfetto-trace") 加载跟踪文件,然后运行trace_data.query("select avg(dur/1 e6 ) from slice where name like '%still%'"),最后打印所花费的平均时间。
通过这种组合,脚本可以在每天早上起床之前运行昨天的性能报告,这比我自己手动分析要容易得多。

不过这里提醒一下,记得确认一下数据。
之前有一个项目,记得数据是avg(dur/1 e6 ),结果大概是0.3 秒,但是后来发现trace文件有bug,导致时间戳写错了,居然用了3 秒。
因此,在使用SQL查询结果后,最好根据实际场景进行判断。

我自己没有运行过这个,但我听说 Perfetto 现在支持与 Prometheus 一起使用并使用 Grafana 来绘制图表。
我不知道它的效果如何。
不管怎样,我想一旦你熟悉了这个工具,分析性能问题就像切菜一样简单,这真是太好了。

sql如何分组选择显示最新的一条数据

去年夏天我在一家小公司担任数据分析师。
那天,老板突然来找我说:“小张,帮我看看这个月的销售数据,找出每个顾客购买次数最多的产品。
”我回忆起SQL语句并打开数据库。

当时我使用了这样的SQL语句:SELECT customer;产品购买金额 (SELECT 客户、产品、购买金额、ROW_NUMBER() OVER (客户 ORDER BY 订单 DESC FROM 购买金额 DESC) AS rn FROM 销售表) WHERE rn = 1 ;
这个语句的意思是,我首先在子查询中按购买金额对每个客户的每个产品进行降序排序,然后通过 ROW_NUMBER() 函数对每个产品进行排名。
外层查询只选择1 级记录,即每个用户购买量最大的产品。

等等,如果客户购买相同数量的产品。
这种方法会丢失一些数据。
例如,如果两个客户都以 1 000 元购买相同的产品。
按照这种方法,只能显示一个。
该怎么办?
我决定再试一次,这次我使用了 DENSE_RANK() 函数,类似于 ROW_NUMBER(),但为并行数据分配相同的排名。
我准备了SQL语句:SELECT customer;产品购买金额(SELECT customer, products, buyamount, DENSE_RANK() OVER (customer orderamount DESC) FROM drn SALES TABLE) WHERE drn = 1 ;
此方法应该解决并发问题;但客户实际购买的产品数量会相同吗?