加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

修改一行SQL代码 性能提升了100倍

发布时间:2018-04-16 20:06:23 所属栏目:语言 来源:CSDN
导读:副标题#e# 在PostgreSQL中修改了一行不明显的代码,把(ANY(ARRAY[...]) 改成 ANY(VALUES(...))),结果查询时间从20s变为0.2s。最初我们学习使用EXPLAN ANALYZE来优化代码,到后来,Postgres社区也成为我们学习提升的一个好帮手,付出总会有回报,我们产品

这次查询共花费22s,我们可以通过下图对这22s进行很直观的了解,其中大部分时间花费在Postgres和OS之间,而磁盘I/O则花费非常少的时间。

修改一行SQL代码 性能提升了100倍

在最低水平,这些查询看起来就像是这些CPU利用率的峰值。在这里主要是想证实一个关键点:数据库不会等待磁盘去读取数据,而是做排序、散列和行比较这些事。

通过Postgres获取与峰值最接近的行数。

修改一行SQL代码 性能提升了100倍

显然,我们的查询在大多数情况下都有条不紊的执行着。

Postgres的性能问题:位图堆扫描

rows_fetched度量与下面的部分计划是一致的: 

Postgres使用位图堆扫描( Bitmap Heap Scan)来读取C表数据。当关键字的数量较少时,它可以在内存中非常高效地使用索引构建位图。如果位图太大,查询优化器会改变其查找数据的方式。在我们这个案例中,需要检查大量的关键字,所以它使用了非常相似的方法来检查候选行并且单独检查与x_key和tag相匹配的每一行。而所有的这些“在内存中加载”和“检查每一行”都需要花费大量的时间。

幸运的是,我们的表有30%都是装载在RAM中,所以在从磁盘上检查行的时候,它不会表现的太糟糕。但在性能上,它仍然存在非常明显的影响。查询过于简单,这是一个非常简单的key查找,所以没有显而易见的数据库或应用重构,它很难找到一些简单的方式来解决这个问题。最后,我们使用 PGSQL-Performance邮件向社区求助。

解决方案

开源帮了我们,经验丰富的且代码贡献量非常多的Tom Lane让我们试试这个:

你能发现有啥不同之处吗?把ARRAY换成了VALUES。

我们使用ARRAY[...]列举出所有的关键字来进行查询,但却欺骗了查询优化器。Values(...)让优化器充分使用关键字索引。仅仅是一行代码的改变,并且没有产生任何语义的改变。

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读