码迷,mamicode.com
首页 > 数据库 > 详细

【转】Postgres SQL sort 操作性能调优

时间:2020-09-24 21:02:04      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:from   情况下   olap   影响   width   获取   sele   explain   post   

这篇文章将以实战的方式结合笔者在项目中真实遇到的情况来讲解。说到SQL,大家可能会遇到一些写法稍微复杂的写法。比如SQL中遇到的有聚合函数sum等,也有遇到使用group by / order by的情况,其实这种情况下SQL的性能可能不是特别好。至少有两种大的解决思路:

    • 减少SQL的压力,把SQL实现的逻辑计算相关,用code的方式去解决。即释放数据库后端宝贵的计算资源。算是重构SQL,这种方式代价稍微要高些,因为要更改code的实现逻辑,也要规划好新的SQL的结构。目的就是为了在SQL中去掉order排序/group分组这类比较耗费资源的部分。


    • 如果前提是我们的SQL不能动,那么要怎么去优化呢?下面会一步步和大家解释在postgres中怎么调优order by SQL语句。

      step1:

      在Postgres中创建测试表,创建表SQL如下:

CREATE TABLE public.sort_test
(
    id bigint NOT NULL,
    salary numeric NOT NULL,
    CONSTRAINT sort_test_pkey PRIMARY KEY (id)
)

TABLESPACE pg_default;

             step2:

        在测试表中插入多条数据,如下SQL,可以往上表中插入500万条数据。

insert into sort_test select generate_series(1,5000000),generate_series(1,5000000);

           step3:

        评估order by 性能问题,假设要评估select语句如下,SQL不是很复杂,可以说明问题即可。

select * from sort_test order by salary;      

          step4:

        分析SQL执行计划,获取执行计划的SQL语句如下:

explain analyze select * from sort_test order by salary;

         step5:

       执行计划如下(注:如果上面SQL语句没有analyze关键字,那么执行计划就不会有Sort Method详细信息和actual time的信息。

  

"Sort  (cost=804270.42..816770.42 rows=5000000 width=14) (actual time=2688.920..3797.378 rows=5000000 loops=1)"
"  Sort Key: salary"
"  Sort Method: external merge  Disk: 122344kB"
"  ->  Seq Scan on sort_test  (cost=0.00..77028.00 rows=5000000 width=14) (actual time=0.071..476.958 rows=5000000 loops=1)"
"Planning Time: 0.193 ms"
"Execution Time: 4038.509 ms"

从以上的执行计划可以看到最小的节点(上面"->"处)的执行时间是0.071 ms,而到上一层Sort,就会发现执行时间就变为了2688.92 ms (注:这边是以actual time作为分析依据,你也可以以cost时间,都是可以的。

以上有个关键信息如下,这就说明此sql在执行的时候,postgres分配的work_mem的内存大小不够,只能从disk处抓取数据处理。那么从内存的角度来优化SQL,就需要增大work_mem参数值,上面说是用了大致122MB disk。而postgres默认的work_mem是 4MB。

Sort Method: external merge  Disk: 122344kB

那么修改work_mem,用下面方法,将work_mem大小设置为1GB.

SET work_mem = 1GB;

       step6:

修改之后,再获取执行计划如下:

"Sort  (cost=633365.42..645865.42 rows=5000000 width=14) (actual time=1241.768..1526.102 rows=5000000 loops=1)"
"  Sort Key: salary"
"  Sort Method: quicksort  Memory: 430984kB"
"  ->  Seq Scan on sort_test  (cost=0.00..77028.00 rows=5000000 width=14) (actual time=0.046..498.029 rows=5000000 loops=1)"
"Planning Time: 0.095 ms"
"Execution Time: 1775.462 ms"

此时,可以看到关键字变为如下所示,sort操作现在是放在了内存中执行的,用了430MB左右的内存,然后执行时间为1241.768 ms,还不到原来执行时间的一半,性能还是有大幅度提升的。

Sort Method: quicksort  Memory: 430984kB"

温馨提示:work_mem在调整时,还是要考虑实际情况,比如我数据库跑一些轻量级的sql比较多,那么设置work_mem值过大的话,反而会影响性能,此时可以小幅度地调整参数值,需要测试多轮,得到适合自己产品的最优解。如果都是哪种OLAP,SQL比较重的情况下,可以调整的幅度大一些,如从4MB调整到1GB.

转自微信公众号【TimTest】,原文地址为:https://mp.weixin.qq.com/s?__biz=MzI2OTYwMDc0MQ==&mid=2247483682&idx=1&sn=bcc5ede4ef228b57711bfc7be12ab6ca&chksm=eadc93a8ddab1abef136057626f292d542c142ac7f6adc38e9d1fd38cf37a759ce1f32921bd0&token=2021082705&lang=zh_CN#rd

 

【转】Postgres SQL sort 操作性能调优

标签:from   情况下   olap   影响   width   获取   sele   explain   post   

原文地址:https://www.cnblogs.com/summerstone/p/13716259.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!