久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

PostgreSQL中HashAggregate與GroupAggregate的區(qū)別是什么

157次閱讀
沒有評論

共計 9395 個字符,預(yù)計需要花費 24 分鐘才能閱讀完成。

本篇內(nèi)容介紹了“PostgreSQL 中 HashAggregate 與 GroupAggregate 的區(qū)別是什么”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓丸趣 TV 小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

案例一

首先我們看一個案例:
測試表:

drop table if exists t_agg;
create table t_agg(bh varchar(20),c1 int,c2 int,c3 int,c4 int,c5 int,c6 int);
insert into t_agg select  GZ01 ,col,col,col,col,col,col from generate_series(1,100000) as col;
insert into t_agg select  GZ02 ,col,col,col,col,col,col from generate_series(1,100000) as col;
insert into t_agg select  GZ03 ,col,col,col,col,col,col from generate_series(1,100000) as col;
insert into t_agg select  GZ04 ,col,col,col,col,col,col from generate_series(1,100000) as col;
insert into t_agg select  GZ05 ,col,col,col,col,col,col from generate_series(1,100000) as col;

執(zhí)行查詢:

testdb=# --  禁用并行
testdb=# set max_parallel_workers_per_gather=0;
testdb=# explain verbose select bh,min(c1),max(c1),min(c2),max(c2),min(c3),max(c3),min(c4),max(c4),min(c5),max(c5) from t_agg group by bh;
 QUERY PLAN 
--------------------------------------------------------------------------------------------------------
 HashAggregate (cost=22427.00..22427.05 rows=5 width=45)
 Output: bh, min(c1), max(c1), min(c2), max(c2), min(c3), max(c3), min(c4), max(c4), min(c5), max(c5)
 Group Key: t_agg.bh
 -  Seq Scan on public.t_agg (cost=0.00..8677.00 rows=500000 width=25)
 Output: bh, c1, c2, c3, c4, c5, c6
(5 rows)

PG 的優(yōu)化器選擇了 HashAggregate.
下面禁用 HashAggregate, 優(yōu)化器只能選擇 GroupAggregate. 可以看到兩者的總成本比較:22427.05 vs 82968.97

testdb=# set enable_hashagg = off;
testdb=# explain verbose select bh,min(c1),max(c1),min(c2),max(c2),min(c3),max(c3),min(c4),max(c4),min(c5),max(c5) from t_agg group by bh;
 QUERY PLAN 
--------------------------------------------------------------------------------------------------------
 GroupAggregate (cost=67968.92..82968.97 rows=5 width=45)
 Output: bh, min(c1), max(c1), min(c2), max(c2), min(c3), max(c3), min(c4), max(c4), min(c5), max(c5)
 Group Key: t_agg.bh
 -  Sort (cost=67968.92..69218.92 rows=500000 width=25)
 Output: bh, c1, c2, c3, c4, c5
 Sort Key: t_agg.bh
 -  Seq Scan on public.t_agg (cost=0.00..8677.00 rows=500000 width=25)
 Output: bh, c1, c2, c3, c4, c5
(8 rows)

案例二
下面用一個寬表來進行測試: 分組鍵值很少, 但聚合列很多

drop table if exists t_agg_width;
create table t_agg_width
(bh varchar(20)
,c1 int,c2 int,c3 int,c4 int,c5 int,c6 int,c7 int,c8 int,c9 int
,c11 int,c12 int,c13 int,c14 int,c15 int,c16 int,c17 int,c18 int,c19 int
,c21 int,c22 int,c23 int,c24 int,c25 int,c26 int,c27 int,c28 int,c29 int
,c31 int,c32 int,c33 int,c34 int,c35 int,c36 int,c37 int,c38 int,c39 int);
insert into t_agg_width 
select  GZ01 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
from generate_series(1,100000) as col;
insert into t_agg_width 
select  GZ02 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
from generate_series(1,100000) as col;
insert into t_agg_width 
select  GZ03 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
from generate_series(1,100000) as col;
insert into t_agg_width 
select  GZ04 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
,col,col,col,col,col,col,col,col,col 
from generate_series(1,100000) as col;
--  禁用 hashagg
set enable_hashagg = off;
--  禁用并行
set max_parallel_workers_per_gather=0;
select bh
,min(c1),min(c2) ,min(c3) ,min(c4) ,min(c5) ,min(c6) ,min(c7) ,min(c8) ,min(c9)
,min(c11),min(c12) ,min(c13) ,min(c14) ,min(c15) ,min(c16) ,min(c17) ,min(c18) ,min(c19)
,min(c21),min(c22) ,min(c23) ,min(c24) ,min(c25) ,min(c26) ,min(c27) ,min(c28) ,min(c29)
,min(c31),min(c32) ,min(c33) ,min(c34) ,min(c35) ,min(c36) ,min(c37) ,min(c38) ,min(c39)
from t_agg_width group by bh;

在這種情況下, 優(yōu)化器仍會選擇 Hash

testdb=# explain verbose select bh
testdb-# ,min(c1),min(c2) ,min(c3) ,min(c4) ,min(c5) ,min(c6) ,min(c7) ,min(c8) ,min(c9)
testdb-# ,min(c11),min(c12) ,min(c13) ,min(c14) ,min(c15) ,min(c16) ,min(c17) ,min(c18) ,min(c19)
testdb-# ,min(c21),min(c22) ,min(c23) ,min(c24) ,min(c25) ,min(c26) ,min(c27) ,min(c28) ,min(c29)
testdb-# ,min(c31),min(c32) ,min(c33) ,min(c34) ,min(c35) ,min(c36) ,min(c37) ,min(c38) ,min(c39)
testdb-# from t_agg_width group by bh;
 QUERY PLAN 
----------------------------------------------------------------------------------------------------------
 HashAggregate (cost=49889.00..49889.04 rows=4 width=149)
 Output: bh, min(c1), min(c2), min(c3), min(c4), min(c5), min(c6), min(c7), min(c8), min(c9), min(c11), min(c12), min(c13),
 min(c14), min(c15), min(c16), min(c17), min(c18), min(c19), min(c21), min(c22), min(c23), min(c24), min(c25), min(c26), min(c27), min(c28), min(c29), min(c31), min(c32), min(c33), min(c34), min(c35), min(c36), min(c37), min(c38), min(c39)
 Group Key: t_agg_width.bh
 -  Seq Scan on public.t_agg_width (cost=0.00..12889.00 rows=400000 width=149)
 Output: bh, c1, c2, c3, c4, c5, c6, c7, c8, c9, c11, c12, c13, c14, c15, c16, c17, c18, c19, c21, c22, c23, c24, c25
, c26, c27, c28, c29, c31, c32, c33, c34, c35, c36, c37, c38, c39
(5 rows)
testdb=# set enable_hashagg = off;
testdb=# explain verbose select bh
,min(c1),min(c2) ,min(c3) ,min(c4) ,min(c5) ,min(c6) ,min(c7) ,min(c8) ,min(c9)
,min(c11),min(c12) ,min(c13) ,min(c14) ,min(c15) ,min(c16) ,min(c17) ,min(c18) ,min(c19)
,min(c21),min(c22) ,min(c23) ,min(c24) ,min(c25) ,min(c26) ,min(c27) ,min(c28) ,min(c29)
,min(c31),min(c32) ,min(c33) ,min(c34) ,min(c35) ,min(c36) ,min(c37) ,min(c38) ,min(c39)
from t_agg_width group by bh;
 QUERY PLAN 
----------------------------------------------------------------------------------------------------------
 GroupAggregate (cost=110266.28..148266.32 rows=4 width=149)
 Output: bh, min(c1), min(c2), min(c3), min(c4), min(c5), min(c6), min(c7), min(c8), min(c9), min(c11), min(c12), min(c13),
 min(c14), min(c15), min(c16), min(c17), min(c18), min(c19), min(c21), min(c22), min(c23), min(c24), min(c25), min(c26), min(c27), min(c28), min(c29), min(c31), min(c32), min(c33), min(c34), min(c35), min(c36), min(c37), min(c38), min(c39)
 Group Key: t_agg_width.bh
 -  Sort (cost=110266.28..111266.28 rows=400000 width=149)
 Output: bh, c1, c2, c3, c4, c5, c6, c7, c8, c9, c11, c12, c13, c14, c15, c16, c17, c18, c19, c21, c22, c23, c24, c25
, c26, c27, c28, c29, c31, c32, c33, c34, c35, c36, c37, c38, c39
 Sort Key: t_agg_width.bh
 -  Seq Scan on public.t_agg_width (cost=0.00..12889.00 rows=400000 width=149)
 Output: bh, c1, c2, c3, c4, c5, c6, c7, c8, c9, c11, c12, c13, c14, c15, c16, c17, c18, c19, c21, c22, c23, c2
4, c25, c26, c27, c28, c29, c31, c32, c33, c34, c35, c36, c37, c38, c39
(8 rows)
testdb=#

下面增大分組鍵值的分布, 同時提高 c1 等列的選擇率, 再次測試:

testdb=# insert into t_agg_width 
testdb-# select  GZ ||col
testdb-# ,mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100) 
testdb-# ,mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100) 
testdb-# ,mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100) 
testdb-# ,mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100),mod(col,100) 
testdb-# from generate_series(1,1000000) as col;
INSERT 0 1000000
testdb=# set enable_hashagg = on;
testdb=# explain verbose select bh
,min(c1),min(c2) ,min(c3) ,min(c4) ,min(c5) ,min(c6) ,min(c7) ,min(c8) ,min(c9)
,min(c11),min(c12) ,min(c13) ,min(c14) ,min(c15) ,min(c16) ,min(c17) ,min(c18) ,min(c19)
,min(c21),min(c22) ,min(c23) ,min(c24) ,min(c25) ,min(c26) ,min(c27) ,min(c28) ,min(c29)
,min(c31),min(c32) ,min(c33) ,min(c34) ,min(c35) ,min(c36) ,min(c37) ,min(c38) ,min(c39)
from t_agg_width group by bh;
 QUERY PLAN 
----------------------------------------------------------------------------------------------------------
 GroupAggregate (cost=440012.46..586553.52 rows=7414 width=149)
 Output: bh, min(c1), min(c2), min(c3), min(c4), min(c5), min(c6), min(c7), min(c8), min(c9), min(c11), min(c12), min(c13),
 min(c14), min(c15), min(c16), min(c17), min(c18), min(c19), min(c21), min(c22), min(c23), min(c24), min(c25), min(c26), min(c27), min(c28), min(c29), min(c31), min(c32), min(c33), min(c34), min(c35), min(c36), min(c37), min(c38), min(c39)
 Group Key: t_agg_width.bh
 -  Sort (cost=440012.46..443866.86 rows=1541757 width=149)
 Output: bh, c1, c2, c3, c4, c5, c6, c7, c8, c9, c11, c12, c13, c14, c15, c16, c17, c18, c19, c21, c22, c23, c24, c25
, c26, c27, c28, c29, c31, c32, c33, c34, c35, c36, c37, c38, c39
 Sort Key: t_agg_width.bh
 -  Seq Scan on public.t_agg_width (cost=0.00..49681.57 rows=1541757 width=149)
 Output: bh, c1, c2, c3, c4, c5, c6, c7, c8, c9, c11, c12, c13, c14, c15, c16, c17, c18, c19, c21, c22, c23, c2
4, c25, c26, c27, c28, c29, c31, c32, c33, c34, c35, c36, c37, c38, c39
(8 rows)
testdb=#

這一次選擇的是 GroupAggregate.

HashAggregate
HashAggregate, 數(shù)據(jù)庫會根據(jù) group by 字段后面的值算出 hash 值, 并在內(nèi)存中維護對應(yīng)的 Hash 表, 比如 select 有 n 個聚合函數(shù), 那么在內(nèi)存中就會維護 n 個 Hash 表. 這種方式使用的內(nèi)存比 GroupAggregate 要大, 內(nèi)存的使用與 group by COLUMN 中的 COLUMN 的唯一鍵值以及聚合列的多少成正比.

GroupAggregate
GroupAggregate, 數(shù)據(jù)庫先將表中的數(shù)據(jù)按 group by 的字段進行排序, 然后對排好序的數(shù)據(jù)進行一次掃描, 計算得到聚合的結(jié)果. 這種方式需要先執(zhí)行一次排序, 計算復(fù)雜度上面要比 HashAggregate 要高, 但這種方法的好處是與 group by COLUMN 中的 COLUMN 的唯一鍵值多寡 / 聚合列多寡無關(guān), 分組鍵值很多而且聚合列很多且列數(shù)據(jù)選擇很高的情況下, 會優(yōu)于 HashAggregate.

“PostgreSQL 中 HashAggregate 與 GroupAggregate 的區(qū)別是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注丸趣 TV 網(wǎng)站,丸趣 TV 小編將為大家輸出更多高質(zhì)量的實用文章!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-24發(fā)表,共計9395字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 成安县| 益阳市| 东安县| 商水县| 锦屏县| 靖安县| 山西省| 会东县| 鄯善县| 武威市| 通辽市| 黄浦区| 海门市| 泉州市| 柯坪县| 固原市| 新宾| 山西省| 东平县| 仪征市| 利川市| 沽源县| 宁波市| 临夏县| 安乡县| 同德县| 驻马店市| 清徐县| 铜山县| 西昌市| 喀喇| 昭苏县| 黔西县| 迁西县| 姚安县| 社旗县| 嵊州市| 广水市| 平山县| 昌图县| 莱阳市|