怎么解決PostgreSQL窗口函數(shù)調(diào)用的限制

這篇文章主要講解了“怎么解決PostgreSQL窗口函數(shù)調(diào)用的限制”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“怎么解決PostgreSQL窗口函數(shù)調(diào)用的限制”吧!

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、天涯ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的天涯網(wǎng)站制作公司

背景

窗口函數(shù)是分析場(chǎng)景常用的,目前(citus 7.5)僅支持兩種場(chǎng)景使用window函數(shù),

1、partition by 必須是分布鍵。

2、where條件里面帶分布鍵的等值過(guò)濾條件。

本質(zhì)上:目前(citus 7.5)window函數(shù)不支持跨shard操作,或者說(shuō)過(guò)程中不進(jìn)行重分布。

而Greenplum這方面做得很好,是一個(gè)完整的MPP數(shù)據(jù)庫(kù)。

citus window函數(shù)的支持

postgres=# \set VERBOSITY verbose  
  
  
postgres=# select row_number() over(partition by bid order by aid) rn,* from pgbench_accounts;  
ERROR:  0A000: could not run distributed query because the window function that is used cannot be pushed down  
HINT:  Window functions are supported in two ways.   
Either add an equality filter on the distributed tables' partition column   
or   
use the window functions with a PARTITION BY clause containing the distribution column  
LOCATION:  DeferErrorIfQueryNotSupported, multi_logical_planner.c:938

滿足以下條件即可支持

1、partition by 必須是分布鍵。

2、where條件里面帶分布鍵的等值過(guò)濾條件。

postgres=# select row_number() over(partition by bid order by aid) rn,* from pgbench_accounts where aid=1;  
 rn | aid | bid | abalance |                                        filler                                          
----+-----+-----+----------+--------------------------------------------------------------------------------------  
  1 |   1 |   1 |        0 |                                                                                       
(1 row)  
  
postgres=# select row_number() over(partition by aid order by bid) rn,* from pgbench_accounts  limit 1;  
 rn | aid | bid | abalance |                                        filler                                          
----+-----+-----+----------+--------------------------------------------------------------------------------------  
  1 | 298 |   1 |        0 |                                                                                       
(1 row)

執(zhí)行計(jì)劃

postgres=# explain verbose select row_number() over(partition by aid order by bid) rn,* from pgbench_accounts  limit 1;  
                                                                       QUERY PLAN                                                                          
---------------------------------------------------------------------------------------------------------------------------------------------------------  
 Limit  (cost=0.00..0.00 rows=0 width=0)  
   Output: remote_scan.rn, remote_scan.aid, remote_scan.bid, remote_scan.abalance, remote_scan.filler  
   ->  Custom Scan (Citus Real-Time)  (cost=0.00..0.00 rows=0 width=0)  
         Output: remote_scan.rn, remote_scan.aid, remote_scan.bid, remote_scan.abalance, remote_scan.filler  
         Task Count: 128  
         Tasks Shown: One of 128  
         ->  Task  
               Node: host=172.24.211.224 port=1921 dbname=postgres  
               ->  Limit  (cost=705.99..706.01 rows=1 width=105)  
                     Output: (row_number() OVER (?)), pgbench_accounts.aid, pgbench_accounts.bid, pgbench_accounts.abalance, pgbench_accounts.filler  
                     ->  WindowAgg  (cost=705.99..860.95 rows=7748 width=105)  
                           Output: row_number() OVER (?), pgbench_accounts.aid, pgbench_accounts.bid, pgbench_accounts.abalance, pgbench_accounts.filler  
                           ->  Sort  (cost=705.99..725.36 rows=7748 width=97)  
                                 Output: pgbench_accounts.aid, pgbench_accounts.bid, pgbench_accounts.abalance, pgbench_accounts.filler  
                                 Sort Key: pgbench_accounts.aid, pgbench_accounts.bid  
                                 ->  Seq Scan on public.pgbench_accounts_106812 pgbench_accounts  (cost=0.00..205.48 rows=7748 width=97)  
                                       Output: pgbench_accounts.aid, pgbench_accounts.bid, pgbench_accounts.abalance, pgbench_accounts.filler  
(17 rows)  
  
postgres=# explain verbose select row_number() over(partition by bid order by aid) rn,* from pgbench_accounts where aid=1;  
                                                                         QUERY PLAN                                                                            
-------------------------------------------------------------------------------------------------------------------------------------------------------------  
 Custom Scan (Citus Router)  (cost=0.00..0.00 rows=0 width=0)  
   Output: remote_scan.rn, remote_scan.aid, remote_scan.bid, remote_scan.abalance, remote_scan.filler  
   Task Count: 1  
   Tasks Shown: All  
   ->  Task  
         Node: host=172.24.211.232 port=1921 dbname=postgres  
         ->  WindowAgg  (cost=2.51..2.53 rows=1 width=105)  
               Output: row_number() OVER (?), aid, bid, abalance, filler  
               ->  Sort  (cost=2.51..2.51 rows=1 width=97)  
                     Output: aid, bid, abalance, filler  
                     Sort Key: pgbench_accounts.bid  
                     ->  Index Scan using pgbench_accounts_pkey_106819 on public.pgbench_accounts_106819 pgbench_accounts  (cost=0.28..2.50 rows=1 width=97)  
                           Output: aid, bid, abalance, filler  
                           Index Cond: (pgbench_accounts.aid = 1)  
(14 rows)

Citus未在window調(diào)用中支持重分布的過(guò)程。

greenplum window函數(shù)的支持

支持任意姿勢(shì)的window調(diào)用

postgres=# create table t(id int, c1 int, c2 int);  
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Greenplum Database data distribution key for this table.  
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.  
CREATE TABLE  
  
postgres=# insert into t select random()*100000, random()*10, random()*100 from generate_series(1,10000000);  
INSERT 0 10000000  
  
postgres=# explain select row_number() over (partition by c1 order by id) rn,* from t ;  
                                                    QUERY PLAN                                                      
------------------------------------------------------------------------------------------------------------------  
 Gather Motion 33:1  (slice2; segments: 33)  (cost=1477974.88..1553064.94 rows=10012008 width=12)  
   ->  Window  (cost=1477974.88..1553064.94 rows=303395 width=12)  
         Partition By: c1  
         Order By: id  
         ->  Sort  (cost=1477974.88..1503004.90 rows=303395 width=12)  
               Sort Key: c1, id  
               // 以下在citus中用臨時(shí)表代替  
	       ->  redistribute Motion 33:33  (slice1; segments: 33)  (cost=0.00..313817.24 rows=303395 width=12)  
                     Hash Key: c1  
                     ->  Seq Scan on t  (cost=0.00..113577.08 rows=303395 width=12)  
 Optimizer status: legacy query optimizer  
(10 rows)

甚至一個(gè)SQL中支持多個(gè)不同維度的partition

postgres=# explain select row_number() over (partition by c1 order by id) rn1, row_number() over (partition by c2 order by c1) rn2, * from t ;  
                                                                   QUERY PLAN                                                                     
------------------------------------------------------------------------------------------------------------------------------------------------  
 Gather Motion 33:1  (slice3; segments: 33)  (cost=3017582.83..3192792.97 rows=10012008 width=12)  
   ->  Subquery Scan coplan  (cost=3017582.83..3192792.97 rows=303395 width=12)  
         ->  Window  (cost=3017582.83..3092672.89 rows=303395 width=12)  
               Partition By: coplan.c1  
               Order By: coplan.id  
               ->  Sort  (cost=3017582.83..3042612.85 rows=303395 width=12)  
                     Sort Key: coplan.c1, coplan.id  
                     // 以下在citus中用臨時(shí)表代替  
		     ->  Redistribute Motion 33:33  (slice2; segments: 33)  (cost=1477974.88..1853425.18 rows=303395 width=12)  
                           Hash Key: coplan.c1  
                           ->  Subquery Scan coplan  (cost=1477974.88..1653185.02 rows=303395 width=12)  
                                 ->  Window  (cost=1477974.88..1553064.94 rows=303395 width=12)  
                                       Partition By: t.c2  
                                       Order By: t.c1  
                                       ->  Sort  (cost=1477974.88..1503004.90 rows=303395 width=12)  
                                             Sort Key: t.c2, t.c1  
                                             // 以下在citus中用臨時(shí)表代替  
					     ->  Redistribute Motion 33:33  (slice1; segments: 33)  (cost=0.00..313817.24 rows=303395 width=12)  
                                                   Hash Key: t.c2  
                                                   ->  Seq Scan on t  (cost=0.00..113577.08 rows=303395 width=12)  
 Optimizer status: legacy query optimizer  
(19 rows)

感謝各位的閱讀,以上就是“怎么解決PostgreSQL窗口函數(shù)調(diào)用的限制”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)怎么解決PostgreSQL窗口函數(shù)調(diào)用的限制這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

本文名稱(chēng):怎么解決PostgreSQL窗口函數(shù)調(diào)用的限制
網(wǎng)址分享:http://muchs.cn/article24/ihjpje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序手機(jī)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航靜態(tài)網(wǎng)站、ChatGPT、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)