0
加载中

在 Amplitude,我们的目标是提供易于使用的交互式产品分析服务,这样每个人都可以找到他们关于产品问题的答案。为了提供良好的用户体验,Amplitude 需要快速提供这些答案。所以,当我们的一个客户抱怨在 Amplitude UI 中加载事件属性的下拉时间太久时,我们开始深入研究其中的问题。

通过跟踪不同级别的延迟,我们判断出一个特定的 PostgreSQL 查询需要 20 秒才能完成。这让我们有点意外,因为两个表都在 joined column 上都有索引。

缓慢的查询

这个查询的 PostgreSQL 执行计划是没有预料到的。即使两个表都有索引,PostgreSQL 还是使用 hash join 进行了顺序扫描(sequential scan)。在一张大表上进行顺序扫描占据了大部分的查询时间。


导致查询变慢的执行计划

亚林瓜子
翻译于 2017/11/27 17:20
0

我最初怀疑这可能是由于碎片化造成的。但是在检查数据后,我意识到这个表只是附加的,表上并没有多少删除操作。鉴于使用 vacuum 的回收空间在这里不是很有帮助,所以我开始从其他方面下手。接下来,我用另一个客户端进行相同的查询,但响应时间很好。令我惊讶的是,查询执行计划看起来完全不同!

在另一个 APP 上的类似查询的执行计划

有趣的是,app A 的访问数据仅比 app B 多了 10 倍,但响应时间却增加了 3000 倍。

为了分析 PostgreSQL 在选择 Hash Join 之前考虑的替代查询计划,我禁用了 hash join 并重新执行该查询。

缓慢查询的可选执行计划

Tocy
翻译于 2017/11/27 17:58
0

就是因为这个!使用嵌套循环(Nested Loop)代替 Hash Join 时,虽然是相同的查询但速度提高了50倍。那为什么 PostgreSQL 为 app A 了选择一个更糟糕的计划呢?

仔细观察这两个计划的预估成本和实际运行时间,预估时间与实际运行时间的比率是非常不同的。造成这种差异的主要原因是顺序扫描的成本估算。PostgreSQL 估计,顺序扫描比 4000+ 的索引扫描更好,但实际上索引扫描速度要快 50 倍。

这让我选择使用 'random_page_cost' 和 'seq_page_cost' 配置选项。对于 'random_page_cost','seq_page_cost',默认的 PostgreSQL 值分别为 4 和 1,这些值是针对 HDD 进行调整的,随机访问磁盘比顺序访问更耗时。然而,这些成本对于我们使用固态驱动器进行 gp2 EBS volume 的部署是不准确的。对于我们的部署,随机和顺序访问的速度几乎是一样的。

Tocy
翻译于 2017/11/27 17:52
0

我修改 'random_page_const' 的值为 1,重试了查询。这次 PostgreSQL 使用嵌套查询(Nested Loop)后快了 50 倍,更改后我们也注意到 PostgreSQL 的最大响应时间显着下降。

慢查询的性能显著提升

如果你正在使用 SSD 并以默认配置运行 PostgreSQL,我鼓励你尝试调整 random_page_cost&seq_page_cost,你可能会对一些巨大的性能改进感到惊讶。

还有其他的参数调整给你带来巨大的改进? 在评论中和我们分享吧!

Tot_ziens
翻译于 2017/11/27 16:55
0
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(0)

返回顶部
顶部