PostgreSQL视图查询的性能

PostgreSQL视图查询的性能,postgresql,query-performance,Postgresql,Query Performance,我有一个普通视图,它是从SQL Server 2000迁移到PostgreSQL 11的,在SQL Server中执行得很好,但是在PostgreSQL中,它花费的时间是后者的两倍多,太长了 我对表进行了真空处理并创建了索引,但可能我遗漏了一些东西。我需要一些帮助来微调查询 SELECT h.bg AS bg, count(*) AS cnt, sum(h.retail_score) AS retail_score FROM ( SELECT x.bg,

我有一个普通视图,它是从SQL Server 2000迁移到PostgreSQL 11的,在SQL Server中执行得很好,但是在PostgreSQL中,它花费的时间是后者的两倍多,太长了

我对表进行了真空处理并创建了索引,但可能我遗漏了一些东西。我需要一些帮助来微调查询

SELECT h.bg AS bg,
    count(*) AS cnt,
    sum(h.retail_score) AS retail_score
   FROM ( SELECT x.bg,
                CASE x.void_category
                    WHEN 'DEPARTMENT STORE'::citext THEN 0.6
                    WHEN 'THEATERS/CINEMA'::citext THEN 0.5
                    WHEN 'SUPERCENTER'::citext THEN 0.35
                    WHEN 'CLOTHING AND APPAREL'::citext THEN 0.3
                    WHEN 'FOOTWEAR/SHOES'::citext THEN 0.2
                    WHEN 'HOME SPECIALTY'::citext THEN 0.2
                    WHEN 'HOME IMPROVEMENT'::citext THEN 0.15
                    WHEN 'OFFICE SUPPLY/SERVICES'::citext THEN 0.15
                    WHEN 'PET SUPPLIES/SERVICES'::citext THEN 0.15
                    WHEN 'BOOKSTORE'::citext THEN 0.15
                    WHEN 'RESTAURANT - FINE DINING'::citext THEN 0.15
                    WHEN 'GROCERY STORE'::citext THEN 0.15
                    WHEN 'SPORTING GOODS'::citext THEN 0.12
                    WHEN 'SPECIALTY RETAIL'::citext THEN 0.1
                    WHEN 'HOBBIES, TOYS AND CRAFTS'::citext THEN 0.09
                    WHEN 'OTHER FOOD/BEVERAGE'::citext THEN 0.08
                    WHEN 'RESTAURANT - CASUAL'::citext THEN 0.07
                    WHEN 'CONSUMER ELECTRONICS'::citext THEN 0.07
                    WHEN 'FITNESS AND GYMS'::citext THEN 0.05
                    WHEN 'GENERAL MERCHANDISE'::citext THEN 0.05
                    WHEN 'PHARMACY/DRUG STORE'::citext THEN 0.04
                    WHEN 'PAYDAY LOAN'::citext THEN 0.02
                    WHEN 'HAIR, SKIN AND NAILS'::citext THEN 0.01
                    WHEN 'RESTAURANT - OTHER'::citext THEN 0.01
                    WHEN 'RESTAURANT - QUICK SERVICE'::citext THEN 0.01
                    WHEN 'COFFEE SHOP'::citext THEN 0.01
                    ELSE 0::numeric
                END AS retail_score
           FROM sometable x
          WHERE x.void_include = 'Y'::citext) h
  GROUP BY h.bg;
执行计划:

"Finalize GroupAggregate  (cost=100341.22..155233.07 rows=78181 width=53) (actual time=19217.400..73474.255 rows=138934 loops=1)"
"  Group Key: sometable.bg"
"  ->  Gather Merge  (cost=100341.22..152692.19 rows=156362 width=53) (actual time=19216.226..72095.206 rows=278778 loops=1)"
"        Workers Planned: 2"
"        Workers Launched: 2"
"        ->  Partial GroupAggregate  (cost=99341.20..133644.11 rows=78181 width=53) (actual time=18448.896..45748.827 rows=92926 loops=3)"
"              Group Key: sometable.bg"
"              ->  Sort  (cost=99341.20..100452.06 rows=444342 width=31) (actual time=18448.677..21747.908 rows=355865 loops=3)"
"                    Sort Key: sometable.bg"
"                    Sort Method: external merge  Disk: 19064kB"
"                    Worker 0:  Sort Method: external merge  Disk: 10912kB"
"                    Worker 1:  Sort Method: external merge  Disk: 13016kB"
"                    ->  Parallel Index Scan using idx_ix_xd_here_9 on sometable  (cost=0.43..47026.01 rows=444342 width=31) (actual time=0.197..746.601 rows=355865 loops=3)"
"                          Index Cond: (void_include = 'Y'::citext)"
"Planning Time: 0.470 ms"
"Execution Time: 73499.182 ms"
我想看看我做错了什么或忘记了什么,并学习改进SQL查询

根据Laurenz的建议,我尝试了以下方法:但仍然不好…:(


您应该增加
work\u mem
以加快查询速度


然后可以在内存中执行慢速排序,您甚至可以得到一个
HashAggregate
,而不是
GroupAggregate
,这样可以完全避免排序。

您应该增加
work\u mem
以加快查询速度


然后可以在内存中执行慢速排序,您甚至可以使用
HashAggregate
而不是
GroupAggregate
,这样可以完全避免排序。

您可以显示SQL Server版本吗?需要查看是否运行相同的类型转换。您是否尝试将这些值放入到一张桌子(或只是一个CTE)连接到它?您可以消除子查询。内部连接有帮助,但我注意到,当我使用case语句时,查询性能会下降。我所做的是将静态数据保存到另一个表中,就像查找一样,并进行了内部连接,但在我的场景中,case语句似乎是罪魁祸首。您能显示SQL Server版本吗?需要吗查看是否运行相同的类型转换。您是否尝试过将这些值放入表(或只是CTE)而不是big case语句连接到它?您可以消除子查询。内部连接有帮助,但我注意到,当我使用case语句时,查询性能会下降。我所做的是将静态数据保存到另一个表中,就像查找一样,并进行了内部连接,但在我的场景中,case语句似乎是罪魁祸首。
SET work_mem = '256MB';
"Finalize HashAggregate  (cost=98417.89..99395.15 rows=78181 width=53) (actual time=40369.734..40511.007 rows=138934 loops=1)"
"  Group Key: sometable.bg"
"  ->  Gather  (cost=80240.80..96854.27 rows=156362 width=53) (actual time=38567.902..38978.588 rows=276820 loops=1)"
"        Workers Planned: 2"
"        Workers Launched: 2"
"        ->  Partial HashAggregate  (cost=79240.80..80218.07 rows=78181 width=53) (actual time=38350.897..38449.107 rows=92273 loops=3)"
"              Group Key: sometable.bg"
"              ->  Parallel Index Scan using idx_ix_xd_here_9 on sometable  (cost=0.43..47026.01 rows=444342 width=31) (actual time=0.173..677.385 rows=355865 loops=3)"
"                    Index Cond: (void_include = 'Y'::citext)"
"Planning Time: 0.333 ms"
"Execution Time: 40546.180 ms"

SET work_mem = '1024MB';

"Finalize HashAggregate  (cost=98417.89..99395.15 rows=78181 width=53) (actual time=35633.509..35717.539 rows=138934 loops=1)"
"  Group Key: sometable.bg"
"  ->  Gather  (cost=80240.80..96854.27 rows=156362 width=53) (actual time=34612.949..34783.491 rows=277896 loops=1)"
"        Workers Planned: 2"
"        Workers Launched: 2"
"        ->  Partial HashAggregate  (cost=79240.80..80218.07 rows=78181 width=53) (actual time=34369.871..34446.030 rows=92632 loops=3)"
"              Group Key: sometable.bg"
"              ->  Parallel Index Scan using idx_ix_xd_here_9 on sometable  (cost=0.43..47026.01 rows=444342 width=31) (actual time=0.176..585.221 rows=355865 loops=3)"
"                    Index Cond: (void_include = 'Y'::citext)"
"Planning Time: 0.337 ms"
"Execution Time: 35735.606 ms"