ãã§ã«ãå©çšãããŠããæ¹ãå€ãã - åœç€Ÿã® PostgreSQL èšç»èŠèŠåãµãŒãã¹ã¯ããã®è¶ èœåã® XNUMX ã€ã§ãããµãŒã㌠ãã°ã®èªã¿ã«ããéšåãèªèããŠããªãå¯èœæ§ããããŸã...

... 察å¿ãããã©ã³ ããŒãã®ã³ã³ããã¹ã ãã³ããå«ããçŸããèšèšãããã¯ãšãªã«å€æãããŸãã

圌ã®ç¬¬äºéšã®è»¢åã§ã¯ã ã©ããã£ãŠãããå®çŸã§ããããã話ããŸãã
å žåçãªã¯ãšãª ããã©ãŒãã³ã¹ã®åé¡ãšãã®è§£æ±ºçã«ç¹åããæåã®éšåã®ãã©ã³ã¹ã¯ãªããã¯ã次ã®èšäºã«ãããŸãã .

ãŸããè²ãä»ãå§ããŸããã - ãããŠãèšç»ã«è²ãä»ããããšã¯ãããããŸããããã§ã«è²ãä»ããŠããŸãããã§ã«çŸãããŠããããããã§ããããªã¯ãšã¹ãããããŸãã
ãã®ãããªãã©ãŒããããããŠããªããã·ãŒããã§ã¯ããã°ããååŸãããªã¯ãšã¹ããéåžžã«èŠèŠãããäžäŸ¿ã§ããããã«æããŸããã

ç¹ã«ãéçºè
ãã³ãŒãå
ã®ãªã¯ãšã¹ãã®æ¬æã XNUMX è¡ã«ã貌ãä»ãããå Žå (ããã¯ãã¡ããã¢ã³ããã¿ãŒã³ã§ãããå®éã«ã¯èµ·ãããŸã)ã ææªïŒ
ãããäœãšããã£ãšç¶ºéºã«æããŠã¿ãŸãããã

ãããŠããããçŸããæãããšãã§ããã°ãã€ãŸããªã¯ãšã¹ãã®æ¬äœãåè§£ããŠå
ã«æ»ãããšãã§ããã°ããã®ãªã¯ãšã¹ãã®åãªããžã§ã¯ãã«ãã³ããã€ãŸãèšç»ã®å¯Ÿå¿ããç¹ã§äœãèµ·ãã£ããããæ·»ä»ãããããšãã§ããŸãã
ã¯ãšãªæ§æããªãŒ
ãããè¡ãã«ã¯ããŸããªã¯ãšã¹ããè§£æããå¿
èŠããããŸãã

ãªããªãç§ãã¡ã¯æã£ãŠãããã ãããããã¢ãžã¥ãŒã«ãäœæããŸããã ã å®éãããã㯠PostgreSQL ããŒãµãŒèªäœã®å
éšã«æ¡åŒµãããããã€ã³ãã£ã³ã°ãã§ãã ã€ãŸããææ³ã¯åçŽã«ãã€ããªã§ã³ã³ãã€ã«ãããNodeJS ããææ³ãžã®ãã€ã³ãã£ã³ã°ãäœæãããŸãã ç§ãã¡ã¯ä»ã®äººã®ã¢ãžã¥ãŒã«ãåºç€ãšããŠæ¡çšããŸãã - ããã«ã¯å€§ããªç§å¯ã¯ãããŸããã
ãªã¯ãšã¹ãã®æ¬æãå
¥åãšããŠé¢æ°ã«å
¥åããŸããåºåã§ã¯ãè§£æãããæ§æããªãŒã JSON ãªããžã§ã¯ãã®åœ¢åŒã§ååŸãããŸãã

ããã§ããã®ããªãŒãéæ¹åã«å®è¡ããå¿
èŠãªã€ã³ãã³ããè²ä»ããæžåŒèšå®ã䜿çšããŠãªã¯ãšã¹ããçµã¿ç«ãŠãããšãã§ããŸãã ããããããã¯ã«ã¹ã¿ãã€ãºã§ããŸããããããã¯äŸ¿å©ã ãšæãããŸããã

ã¯ãšãªããŒããšãã©ã³ããŒãã®ãããã³ã°
ããã§ãæåã®ã¹ãããã§åæãããã©ã³ãš XNUMX çªç®ã®ã¹ãããã§åæããã¯ãšãªãã©ã®ããã«çµã¿åãããããšãã§ããããèŠãŠã¿ãŸãããã
ç°¡åãªäŸãèŠãŠã¿ãŸããããCTE ãçæãããããã XNUMX åèªã¿åãã¯ãšãªããããŸãã 圌ã¯ãã®ãããªèšç»ãç«ãŠãŸãã

CTE
ããèŠããšãããŒãžã§ã³ 12 ãŸã§ (ãŸãã¯ããŒã¯ãŒãããå§ããŸã) MATERIALIZED) ãã©ãŒã¡ãŒã·ã§ã³ .

ããã¯ããªã¯ãšã¹ãå
ã®ã©ããã« CTE çæãããããã©ã³å
ã®ã©ããã«ããŒããããå Žåãæå³ããŸãã CTEããã®åŸããããã®ããŒãã¯ééããªãäºãã«ãæŠããã®ã§ãããã«ããããçµåã§ããŸãã
ã¢ã¹ã¿ãªã¹ã¯ã®åé¡: CTE ã¯ãã¹ãã§ããŸãã

ãã¹ããéåžžã«äžååãªãã®ããåãååã®ãã®ãããããŸãã ããšãã°ãå
éšã§ã¯æ¬¡ã®ããšãã§ããŸãã CTE A äœã CTE Xãå
éšã§ã¯åãã¬ãã«ã«ãããŸã CTE B åã³ãããè¡ã CTE X:
WITH A AS (
WITH X AS (...)
SELECT ...
)
, B AS (
WITH X AS (...)
SELECT ...
)
...æ¯èŒããå Žåã¯ããã®ããšãçè§£ããå¿ èŠããããŸãã ããããç®ã§èŠãŠãçè§£ããããšã¯ãããšãèšç»ãèŠãŠãããªã¯ãšã¹ãã®æ¬æãèŠãŠããéåžžã«å°é£ã§ãã CTE çæãè€éã§å ¥ãåã«ãªã£ãŠããããªã¯ãšã¹ãã倧ããå Žåãããã¯å®å šã«ç¡æèã§ãã
é£å
ã¯ãšãªã«ããŒã¯ãŒããããå Žå UNION [ALL] (XNUMX ã€ã®ãµã³ãã«ãçµåããæŒç®å)ããã©ã³ã§ã¯æ¬¡ã®ããããã®ããŒãã«å¯Ÿå¿ããŸãã AppendããŸãã¯ããã€ã Recursive Union.

ãäžãã«ãããã® UNION - ããã¯ããŒãã®æåã®åå«ã§ãããXNUMX çªç®ã®ãäžãã«ãããŸãã ã¹ã«ãŒããå Žå UNION ããã€ãã®ãããã¯ãäžåºŠã«ãæ¥çãããŸãã Append- ããŒãã¯äŸç¶ãšã㊠XNUMX ã€ã ãã§ãããXNUMX ã€ã§ã¯ãªããå€ãã®åããã®é åºã§ååšããŸãã
(...) -- #1
UNION ALL
(...) -- #2
UNION ALL
(...) -- #3Append
-> ... #1
-> ... #2
-> ... #3
ã¢ã¹ã¿ãªã¹ã¯ã®åé¡: ååž°çãµã³ããªã³ã°çæã®å
éš (WITH RECURSIVE) è€æ°ã®å ŽåããããŸã UNIONã ãã ããæåŸã®ãããã¯ã®åŸã®æåŸã®ãããã¯ã ããåžžã«ååž°çã§ã UNIONã äžèšã®ãã®ã¯ãã¹ãŠåãã§ãããç°ãªããŸã UNION:
WITH RECURSIVE T AS(
(...) -- #1
UNION ALL
(...) -- #2, ÑÑÑ ÐºÐŸÐœÑаеÑÑÑ Ð³ÐµÐœÐµÑаÑÐžÑ ÑÑаÑÑПвПгП ÑПÑÑПÑÐœÐžÑ ÑекÑÑÑОО
UNION ALL
(...) -- #3, ÑПлÑкП ÑÑÐŸÑ Ð±Ð»ÐŸÐº ÑекÑÑÑОвМÑй О ÐŒÐŸÐ¶ÐµÑ ÑПЎеÑжаÑÑ ÐŸÐ±ÑаÑеМОе к T
)
... ãŸãããã®ãããªäŸããçªãæ¢ãããããšãã§ããå¿
èŠããããŸãã ãã®äŸã§ã¯ã次ã®ããšãããããŸãã UNION-ç§ãã¡ã®ãªã¯ãšã¹ãã«ã¯ 3 ã€ã®ã»ã°ã¡ã³ãããããŸããã ãããã£ãŠãXNUMX ã€ã¯ã UNION äžèŽ Append-ããŒãããããŠä»ã®ããŒããž - Recursive Union.

èªã¿åã/æžã蟌ã¿ããŒã¿
ãã¹ãŠãã¬ã€ã¢ãŠãããããªã¯ãšã¹ãã®ã©ã®éšåãèšç»ã®ã©ã®éšåã«å¯Ÿå¿ããããããããŸããã ãããŠããããã®äœåã®äžã§ãç§ãã¡ã¯ãèªã¿ãããããªããžã§ã¯ããç°¡åãã€èªç¶ã«èŠã€ããããšãã§ããŸãã
ã¯ãšãªã®èгç¹ããã¯ããããããŒãã«ãªã®ã CTE ãªã®ãã¯ããããŸãããããããã¯åãããŒãã«ãã£ãŠæå®ãããŠããŸã RangeVarã ãå¯èªæ§ãã®èгç¹ããèŠããšããããããªãéå®ãããããŒãã®ã»ããã§ãã
Seq Scan on [tbl]Bitmap Heap Scan on [tbl]Index [Only] Scan [Backward] using [idx] on [tbl]CTE Scan on [cte]Insert/Update/Delete on [tbl]
ç§ãã¡ã¯ãã©ã³ãšã¯ãšãªã®æ§é ããããã¯ã®å¯Ÿå¿é¢ä¿ããªããžã§ã¯ãã®ååãç¥ã£ãŠãããXNUMX 察 XNUMX ã®æ¯èŒãè¡ããŸãã

ãŸã ã¿ã¹ã¯ãã¢ã¹ã¿ãªã¹ã¯ä»ããã ãªã¯ãšã¹ããåãåããå®è¡ããŸãããšã€ãªã¢ã¹ã¯ãããŸãããåã CTE ãããªã¯ãšã¹ãã XNUMX åèªã¿åãã ãã§ãã

èšç»ãèŠãŠã¿ãŸããã - äœãåé¡ã§ãã? ãªããšã€ãªã¢ã¹ããã£ãã®ã§ãããã? ç§ãã¡ã¯ãããæ³šæããŸããã§ããã 圌ã¯ãã®ãããªãæ°åããã©ãã§å
¥æããã®ã§ããããïŒ
PostgreSQL èªäœãããã远å ããŸãã ãããçè§£ããå¿ èŠãããã ãã§ã ãŸãã«ãã®ãããªå¥å ç§ãã¡ã«ãšã£ãŠã¯ãèšç»ãšã®æ¯èŒãç®çãšããŠãããæå³ã¯ãªããåã«ããã«è¿œå ãããŠããã ãã§ãã åœŒã«æ³šæãæããªãããã«ããŸãããã
2çªç® ã¿ã¹ã¯ãã¢ã¹ã¿ãªã¹ã¯ä»ãã: ããŒãã£ã·ã§ã³åãããããŒãã«ããèªã¿åããè¡ã£ãŠããå ŽåãããŒããååŸããŸãã Append ãŸã㯠Merge Appendã倿°ã®ãåäŸãã§æ§æããããããããäœããã®åœ¢ã§ ScanããŒãã«ã»ã¯ã·ã§ã³ãã: Seq Scan, Bitmap Heap Scan ãŸã㯠Index Scanã ãã ãããããã®å Žåã§ãããããã®ãåãã¯è€éãªã¯ãšãªã§ã¯ãããŸããããããããããã®ããŒããä»ã®ããŒããšåºå¥ããæ¹æ³ã§ãã Append пÑО UNION.

ç§ãã¡ã¯ãã®ãããªçµã³ç®ããçè§£ãããããããäžã€ã®å±±ãã«éããŠããèšããŸããmegatable ããèªã¿åã£ããã®ã¯ãã¹ãŠãããšããªãŒã®äžã«ãããŸã".
ãåçŽãªãããŒã¿åä¿¡ããŒã

Values Scan èšç»çã«å¯Ÿå¿ããŠãã VALUES ãªã¯ãšã¹ãã®äžã§ã
Result ãªãã®ãªã¯ãšã¹ãã§ã FROM ã®ãã㪠SELECT 1ã ãŸãã¯æå³çã«èåœã®è¡šçŸãããå Žå WHERE-block (屿§ã衚瀺ãããŸã) One-Time Filter):
EXPLAIN ANALYZE
SELECT * FROM pg_class WHERE FALSE; -- ОлО 0 = 1Result (cost=0.00..0.00 rows=0 width=230) (actual time=0.000..0.000 rows=0 loops=1)
One-Time Filter: false
Function Scan åãååã® SRF ã«ããããã³ã°ãããŸãã
ãããããã¹ããããã¯ãšãªã§ã¯ãã¹ãŠãããè€éã«ãªããŸããæ®å¿µãªãããåžžã«æ¬¡ã®ããã«ãªããšã¯éããŸããã InitPlan/SubPlanã æã
圌ã㯠... Join ãŸã㯠... Anti Joinãç¹ã«æ¬¡ã®ãããªãã®ãæžããšã WHERE NOT EXISTS ...ã ãããŠãããã§ã¯ããããçµã¿åãããããšãåžžã«å¯èœã§ãããšã¯éããŸãããèšç»ã®ããã¹ãã«ã¯ãèšç»ã®ããŒãã«å¯Ÿå¿ããæŒç®åããããŸããã
ãŸã ã¿ã¹ã¯ãã¢ã¹ã¿ãªã¹ã¯ä»ããïŒ ããã€ãã® VALUES ãªã¯ãšã¹ãã®äžã§ã ãã®å Žåãšãã©ã³ã§ã¯ãè€æ°ã®ããŒããååŸããŸãã Values Scan.

ãçªå·ä»ãããµãã£ãã¯ã¹ã¯ãããããäºãã«åºå¥ããã®ã«åœ¹ç«ã¡ãŸãããããã¯ã察å¿ãããã®ãèŠã€ãã£ãé åºã§æ£ç¢ºã«è¿œå ãããŸãã VALUES- ãªã¯ãšã¹ãã«æ²¿ã£ãŠäžããäžã«ãããã¯ããŸãã
ããŒã¿åŠç
ç§ãã¡ã®ãªã¯ãšã¹ãã®å
容ã¯ãã¹ãŠè§£æ±ºãããããã§ããæ®ã£ãŠããã®ã¯ Limit.

ããããããã§ã¯ãã¹ãŠãåçŽã§ã - 次ã®ãããªããŒãã§ã Limit, Sort, Aggregate, WindowAgg, Unique ãªã¯ãšã¹ãå
ã®å¯Ÿå¿ããæŒç®å (ååšããå Žå) ã« XNUMX 察 XNUMX ã§ããããã³ã°ãããŸãã ããã«ã¯ãã¹ã¿ãŒããå°é£ããããŸããã

ç»é²
çµã¿åãããããšãã«åé¡ãçºçãã JOIN èªåãã¡ã®éã§ã ããã¯åžžã«å¯èœã§ãããšã¯éããŸããããå¯èœã§ãã

ã¯ãšãªããŒãµãŒã®èгç¹ããèŠããšã次ã®ãããªããŒãããããŸãã JoinExprãããã«ã¯ã¡ããã© XNUMX ã€ã®å (å·Šå³) ããããŸãã ãããã£ãŠãããã¯ããªã¯ãšã¹ãå
ã® JOIN ã®ãäžãã«ãããã®ãšãJOIN ã®ãäžãã«æžãããŠãããã®ã§ãã
èšç»ã®èгç¹ãããããšãããã XNUMX 人ã¯ãã人ã®åå«ã§ãã * Loop/* Join-ããŒãã Nested Loop, Hash Anti Joinã... - ãããªæãã
åçŽãªããžãã¯ã䜿çšããŠã¿ãŸãããããã©ã³å
ã§äºãã«ãçµåãããããŒãã« A ãš B ãããå Žåããªã¯ãšã¹ãå
ã§ãããã¯æ¬¡ã®ããããã«é
眮ãããŸãã A-JOIN-BãŸã㯠B-JOIN-Aã ãã®ãããªçµã¿åããã詊ããŠã¿ãŸãããããã®éã®çµã¿åããã詊ããŠã¿ãŸãããããšããããã«ããã®ãããªãã¢ããªããªããŸã§ç¶ããŸãã
æ§æããªãŒãååŸããèšç»ãååŸããŠãããããèŠãŠã¿ãŸããã...䌌ãŠããŸãã!

ãããã°ã©ãã®åœ¢ã§åæç»ããŸããã - ããããã§ã«äœãã®ããã«èŠããŸãã

å B ãš C ãåæã«æã€ããŒããããããšã«æ³šæããŠãã ãããé åºã¯æ°ã«ããŸããã ããããçµã¿åãããŠããŒãã®çµµãè£è¿ããŠã¿ãŸãããã

ããäžåºŠèŠãŠã¿ãŸãããã ããã§ãå A ãšã㢠(B + C) ãæã€ããŒããã§ããŸããããããããããšäºææ§ããããŸãã

çŽ æŽãããïŒ ç§ãã¡ã¯ãã®äºäººã§ããããšã倿ããŸãã JOIN ãªã¯ãšã¹ããšãã©ã³ ããŒããæ£åžžã«çµåãããŸããã
æ®å¿µãªããããã®åé¡ã¯å¿
ããã解決ãããããã§ã¯ãããŸããã

ããšãã°ããªã¯ãšã¹ãã®å Žåã A JOIN B JOIN Cèšç»ã§ã¯ããŸããå€åŽãã®ããŒã A ãš C ãæ¥ç¶ãããŸãããããªã¯ãšã¹ãã«ã¯ãã®ãããªæŒç®åã¯ãªãã匷調衚瀺ãããã®ããã³ããæ·»ä»ãããã®ã¯äœããããŸããã æžããšãã®ãã«ã³ãããåæ§ã§ãã A, B.
ããããã»ãšãã©ã®å Žåãã»ãŒãã¹ãŠã®ããŒãããçµåãããŠããªãããããæéå
ã«ãã®çš®ã®ãããã¡ã€ãªã³ã°ãå·ŠåŽã§ååŸã§ããŸããæåéããJavaScript ã³ãŒããåæãããšãã® Google Chrome ã®ããã«ã§ãã åè¡ãšåã¹ããŒãã¡ã³ãã®ãå®è¡ãã«ã©ããããã®æéãããã£ãããããããŸãã

ããããã¹ãŠããã䟿å©ã«äœ¿çšã§ããããã«ãã¹ãã¬ãŒãžãäœæããŸããã ãä¿åããåŸã§é¢é£ãããªã¯ãšã¹ããšãšãã«èšç»ãèŠã€ãããããªã³ã¯ã誰ããšå
±æãããã§ããŸãã
å€èªã§ããªãã¯ãšãªãé©åãªåœ¢åŒã«å€æããã ãã®å Žåã¯ã次ã䜿çšããŸãã .

åºæïŒ habr.com
