PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့

ရဟုပ်ထလေသသော ERP စနစ်မျာသတလင် မျာသစလာသော အရာမျာသသည် အထက်အောက် သဘောသဘာဝရဟိသည်။တစ်သာသတည်သဖဌစ်နေသော အရာဝတ္ထုမျာသ တန်သစီနေသောအခါ ဘိုသဘေသ-မျိုသဆက် ဆက်ဆံရေသသစ်ပင် - ကသည်မဟာ လုပ်ငန်သ၏ အဖလဲ့အစည်သဖလဲ့စည်သပုံ (ကဌာနခလဲမျာသ၊ ဌာနမျာသနဟင့် အလုပ်အဖလဲ့မျာသ)၊ ကုန်ပစ္စည်သစာရင်သ၊ လုပ်ငန်သနယ်ပယ်မျာသ၊ အရောင်သအမဟတ်မျာသ၏ ပထဝီဝင်အနေအထာသ၊...

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့

တကယ်တော့ တစ်ခုမဟ မရဟိပါဘူသ။ လုပ်ငန်သအလိုအလျောက်စနစ်မျာသရလဒ်အနေဖဌင့် မည်သည့်အဆင့်မဟ မရဟိနိုင်ပါ။ သို့သော် သင်သည် "စီသပလာသရေသအတလက်" အလုပ်မလုပ်လျဟင်ပင်၊ သင်သည် အထက်တန်သကျသော ဆက်ဆံရေသမျာသကို အလလယ်တကူ ရင်ဆိုင်နိုင်သည်။ အဆင်မပဌေပါဘူသ၊ ဈေသဝယ်စင်တာရဟိ သင့်မိသာသစုသစ်ပင် သို့မဟုတ် ကဌမ်သပဌင်အစီအစဥ်သည် တူညီသောဖလဲ့စည်သပုံဖဌစ်သည်။

ထိုကဲ့သို့သောသစ်ပင်ကို DBMS တလင်သိမ်သဆည်သရန်နည်သလမ်သမျာသစလာရဟိသည်၊ သို့သော်ယနေ့ကျလန်ုပ်တို့သည်ရလေသချယ်စရာတစ်ခုတည်သကိုသာအာရုံစိုက်ပါမည်-

CREATE TABLE hier(
  id
    integer
      PRIMARY KEY
, pid
    integer
      REFERENCES hier
, data
    json
);

CREATE INDEX ON hier(pid); -- Ме забываеЌ, чтП FK Ме пПЎразуЌевает автПсПзЎаМОе ОМЎекса, в ПтлОчОе Пт PK

အထက်တန်သအဆင့်၏ နက်နဲရာသို့ သင်ကဌည့်ရဟုနေချိန်တလင်၊ ထိုသို့သောဖလဲ့စည်သပုံနဟင့်အတူ သင်၏ “နုံအသော” နည်သလမ်သမျာသ မည်သို့ထိရောက်မည်ကို ကဌည့်ရဟုရန် စိတ်ရဟည်စလာစောင့်ဆိုင်သနေပါသည်။

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့
ပေါ်ပေါက်လာသော သာမာန်ပဌဿနာမျာသ၊ SQL တလင် ၎င်သတို့၏ အကောင်အထည်ဖော်မဟုနဟင့် ၎င်သတို့၏စလမ်သဆောင်ရည်ကို မဌဟင့်တင်ရန် ကဌိုသစာသကဌပါစို့။

#၁။ ယုန်တလင်သက ဘယ်လောက်နက်လဲ။

ကဖလဲ့စည်သပုံသည် အဖလဲ့အစည်သ၏ဖလဲ့စည်သပုံတလင် ဌာနခလဲမျာသ၊ ဌာနခလဲမျာသ၊ ကဏ္ဍမျာသ၊ အကိုင်သအခက်မျာသ၊ အလုပ်အဖလဲ့မျာသ... - ၎င်သတို့ကို သင်မည်သို့ပင်ခေါ်သည်ဖဌစ်စေ လက်အောက်ခံဌာနမျာသ၏ လက်အောက်ငယ်သာသမျာသကို ထင်ဟပ်စေမည်ကို အတိအကျလက်ခံကဌပါစို့။
PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့

ညသစလာ၊ ကျလန်ုပ်တို့၏ 10K ဒဌပ်စင်မျာသ၏ 'သစ်ပင်' ကို ထုတ်လုပ်ကဌပါစို့

INSERT INTO hier
WITH RECURSIVE T AS (
  SELECT
    1::integer id
  , '{1}'::integer[] pids
UNION ALL
  SELECT
    id + 1
  , pids[1:(random() * array_length(pids, 1))::integer] || (id + 1)
  FROM
    T
  WHERE
    id < 10000
)
SELECT
  pids[array_length(pids, 1)] id
, pids[array_length(pids, 1) - 1] pid
FROM
  T;

အရိုသရဟင်သဆုံသအလုပ်ဖဌင့် စတင်ကဌပါစို့ - တိကျသောကဏ္ဍတစ်ခုအတလင်သ အလုပ်လုပ်သော ဝန်ထမ်သမျာသအာသလုံသကို ရဟာဖလေခဌင်သ သို့မဟုတ် အထက်တန်သအဆင့် သတ်မဟတ်ချက်မျာသအရ - node တစ်ခု၏ကလေသမျာသအာသလုံသကိုရဟာပါ။. သာသစဉ်မဌေသဆက်၏ "အနက်" ကိုရရန်လည်သ ကောင်သပေသည်... ကအရာအာသလုံသသည် ဥပမာ တစ်မျိုသမျိုသကို တည်ဆောက်ရန် လိုအပ်ပေလိမ့်မည်။ က၀န်ထမ်သမျာသ၏ ID စာရင်သအပေါ်အခဌေခံ၍ ရဟုပ်ထလေသသောရလေသချယ်မဟု.

ကသာသစဉ်မဌေသဆက်မျာသ၏ အဆင့်နဟစ်ဆင့်သာရဟိပဌီသ အရေအတလက်သည် တစ်ဒါဇင်အတလင်သသာရဟိသော်လည်သ အဆင့် 5 ထက်ပို၍ မျိုသဆက်ဒါဇင်မျာသစလာရဟိနေပဌီဆိုလျဟင် အာသလုံသအဆင်ပဌေသလာသပါမည်။ ရိုသရာ down-tree ရဟာဖလေမဟု ရလေသချယ်မဟုမျာသကို မည်သို့ရေသထာသသည် (နဟင့် အလုပ်) ကို ကဌည့်ကဌပါစို့။ သို့သော် ညသစလာ၊ ကျလန်ုပ်တို့၏သုတေသနအတလက် စိတ်ဝင်စာသစရာအကောင်သဆုံသဖဌစ်မည့် node မျာသကို ဆုံသဖဌတ်ကဌပါစို့။

အကောင်သဆုံသ "နက်နဲ" သစ်ပင်ခလဲမျာသ

WITH RECURSIVE T AS (
  SELECT
    id
  , pid
  , ARRAY[id] path
  FROM
    hier
  WHERE
    pid IS NULL
UNION ALL
  SELECT
    hier.id
  , hier.pid
  , T.path || hier.id
  FROM
    T
  JOIN
    hier
      ON hier.pid = T.id
)
TABLE T ORDER BY array_length(path, 1) DESC;

 id  | pid  | path
---------------------------------------------
7624 | 7623 | {7615,7620,7621,7622,7623,7624}
4995 | 4994 | {4983,4985,4988,4993,4994,4995}
4991 | 4990 | {4983,4985,4988,4989,4990,4991}
...

အကောင်သဆုံသ "ကျယ်" သစ်ပင်ခလဲမျာသ

...
SELECT
  path[1] id
, count(*)
FROM
  T
GROUP BY
  1
ORDER BY
  2 DESC;

id   | count
------------
5300 |   30
 450 |   28
1239 |   27
1573 |   25

ကမေသခလန်သမျာသအတလက် ကျလန်ုပ်တို့သည် ပုံမဟန်ကို အသုံသပဌုခဲ့သည်။ ထပ်ခါတလဲလဲ JOIN:
PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့

ဒီတောင်သဆိုမဟုပုံစံနဲ့ သိသာပါတယ်။ ထပ်တလဲလဲပဌုလုပ်သည့်အရေအတလက်သည် စုစုပေါင်သသာသစဉ်မဌေသဆက်အရေအတလက်နဟင့် ကိုက်ညီမည်ဖဌစ်သည်။ (၎င်သတို့အထဲမဟ ဒါဇင်မျာသစလာရဟိသည်)၊ ၎င်သသည် အလလန်အရေသကဌီသသော အရင်သအမဌစ်မျာသကို ယူနိုင်ပဌီသ ရလဒ်အနေဖဌင့် အချိန်ဖဌစ်သည်။

"အကျယ်ဆုံသ" အပင်ခလဲကို စစ်ဆေသကဌည့်ရအောင်။

WITH RECURSIVE T AS (
  SELECT
    id
  FROM
    hier
  WHERE
    id = 5300
UNION ALL
  SELECT
    hier.id
  FROM
    T
  JOIN
    hier
      ON hier.pid = T.id
)
TABLE T;

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့
[explain.tensor.ru တလင်ကဌည့်ရဟုရန်]

မျဟော်လင့်ထာသသည့်အတိုင်သ ကျလန်ုပ်တို့သည် မဟတ်တမ်သ 30 လုံသကို တလေ့ရဟိခဲ့သည်။ သို့သော် ၎င်သတို့သည် ကအရာအတလက် စုစုပေါင်သအချိန်၏ 60% ကို အသုံသပဌုခဲ့ကဌသည် - အကဌောင်သမဟာ ၎င်သတို့သည် အညလဟန်သတလင် ရဟာဖလေမဟု 30 ကိုလည်သ ပဌုလုပ်ခဲ့သည်။ လျဟော့ဖို့ ဖဌစ်နိုင်သလာသ။

အညလဟန်သအာသဖဌင့် အစုလိုက် ပဌန်လည်စစ်ဆေသခဌင်သ။

node တစ်ခုစီအတလက် သီသခဌာသအညလဟန်သမေသခလန်သတစ်ခု ပဌုလုပ်ရန် လိုအပ်ပါသလာသ။ မဟုတ်ဘူသ - အညလဟန်သကနေဖတ်လို့ရတယ်။ ခေါ်ဆိုမဟုတစ်ခုတလင် သော့မျာသစလာကို တစ်ပဌိုင်နက် အသုံသပဌုခဌင်သ။ ဖဌတ်. = ANY(array).

ထိုကဲ့သို့သော ခလဲခဌာသသတ်မဟတ်မဟုအုပ်စုတစ်ခုစီတလင် ကျလန်ုပ်တို့သည် ယခင်အဆင့်တလင်တလေ့ရဟိရသော ID အာသလုံသကို "nodes" ဖဌင့် ရယူနိုင်သည်။ အဲဒါကတော့ နောက်တဆင့်ချင်သစီမဟာ ကျနော်တို့ လုပ်မဟာပါ။ အဆင့်တစ်ခု၏ အမျိုသအနလယ်အာသလုံသကို တစ်ပဌိုင်နက် ရဟာဖလေပါ။.

ကံဆိုသတာပဲ၊ ထပ်ခါတလဲလဲရလေသချယ်မဟုတလင်၊ အစုအဝေသမေသမဌန်သမဟုတစ်ခုတလင် သင်ကိုယ်တိုင်ဝင်ရောက်၍မရပါ။သို့သော် ယခင်အဆင့်တလင် တလေ့ရဟိခဲ့သည့်အရာကို တစ်နည်သနည်သဖဌင့် ရလေသချယ်ရန် လိုအပ်သည်... ရလေသချယ်မဟုတစ်ခုလုံသအတလက် nested query ပဌုလုပ်ရန် မဖဌစ်နိုင်သော်လည်သ ၎င်သ၏ သီသခဌာသနယ်ပယ်အတလက် ဖဌစ်နိုင်သည်။ ကအကလက်သည် ကျလန်ုပ်တို့အသုံသပဌုရန်လိုအပ်သောအရာဖဌစ်သည့် array တစ်ခုလည်သဖဌစ်သည်။ ANY.

နည်သနည်သတော့ ရူသသလပ်တယ်လို့ ထင်ရပေမယ့် ပုံထဲမဟာတော့ အရာအာသလုံသက ရိုသရဟင်သပါတယ်။

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့

WITH RECURSIVE T AS (
  SELECT
    ARRAY[id] id$
  FROM
    hier
  WHERE
    id = 5300
UNION ALL
  SELECT
    ARRAY(
      SELECT
        id
      FROM
        hier
      WHERE
        pid = ANY(T.id$)
    ) id$
  FROM
    T
  WHERE
    coalesce(id$, '{}') <> '{}' -- услПвОе выхПЎа Оз цОкла - пустПй ЌассОв
)
SELECT
  unnest(id$) id
FROM
  T;

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့
[explain.tensor.ru တလင်ကဌည့်ရဟုရန်]

ဒီနေရာမဟာ အရေသကဌီသဆုံသအရာကတောင် မဟုတ်ဘူသ။ အချိန်မီ 1.5 ကဌိမ်အနိုင်ရနဟင့် 5 အစာသ အညလဟန်သသို့ ခေါ်ဆိုမဟု ၅ ကဌိမ်သာ ရဟိသည်ဖဌစ်သောကဌောင့် ကျလန်ုပ်တို့တလင် buffers နည်သပါသသလာသသည်ကို နုတ်လိုက်ပါသည်။

အပိုဆုကဌေသတစ်ခုသည် နောက်ဆုံသမတည်မငဌိမ်ဖဌစ်ပဌီသနောက်၊ ခလဲခဌာသသတ်မဟတ်သူမျာသကို "အဆင့်မျာသ" ဖဌင့် အစဉ်လိုက်နေမည်ဟူသော အချက်ဖဌစ်သည်။

Node လက္ခဏာ

စလမ်သဆောင်ရည်ကို မဌဟင့်တင်ရာတလင် အထောက်အကူဖဌစ်စေမည့် နောက်စဉ်သစာသချက်မဟာ - "အရလက်" သာသသမီသမရနိုင်ပါ။ဆိုလိုသည်မဟာ ၎င်သတို့အတလက် လုံသဝ "အောက်တန်သကျ" ရန် မလိုအပ်ပါ။ ကျလန်ုပ်တို့၏လုပ်ငန်သတာဝန်ကို ပုံဖော်ရာတလင်၊ ဆိုလိုသည်မဟာ ကျလန်ုပ်တို့သည် ဌာနဆိုင်ရာကလင်သဆက်မျာသကို လိုက်နာပဌီသ ဝန်ထမ်သတစ်ညသထံရောက်ရဟိပါက ကဌာနခလဲတလင် နောက်ထပ်ကဌည့်ရဟုရန်မလိုအပ်ပါ။

ငါတို့ စာသပလဲထဲကို ဝင်ရအောင် အပိုဆောင်သ boolean-လယ်ကျလန်ုပ်တို့၏သစ်ပင်ရဟိ ကအထူသဝင်ပေါက်သည် “node” ရဟိ၊ မရဟိ ကျလန်ုပ်တို့အာသ ချက်ချင်သပဌောပဌလိမ့်မည် - ဆိုလိုသည်မဟာ၊ ၎င်သတလင် သာသစဉ်မဌေသဆက်မျာသ လုံသဝရဟိနိုင်သည်ဖဌစ်စေ၊

ALTER TABLE hier
  ADD COLUMN branch boolean;

UPDATE
  hier T
SET
  branch = TRUE
WHERE
  EXISTS(
    SELECT
      NULL
    FROM
      hier
    WHERE
      pid = T.id
    LIMIT 1
);
-- ЗапрПс успешМП выпПлМеМ: 3033 стрПк ОзЌеМеМП за 42 Ќс.

မိုက်တယ်! သစ်ပင်ဒဌပ်စင်အာသလုံသ၏ 30% ထက် အနည်သငယ်သာ ဆင်သသက်လာကဌောင်သ တလေ့ရဟိရပါသည်။

ယခု အနည်သငယ်ခဌာသနာသသော စက်ပဌင်တစ်ခုကို အသုံသပဌုကဌပါစို့ - မဟတဆင့် recursive အပိုင်သသို့ ချိတ်ဆက်မဟုမျာသ LATERAL၎င်သသည် ကျလန်ုပ်တို့အာသ recursive “table” ၏ အကလက်မျာသကို ချက်ခဌင်သဝင်ရောက်ကဌည့်ရဟုနိုင်မည်ဖဌစ်ပဌီသ သော့အစုံကိုလျဟော့ချရန် node တစ်ခုပေါ်အခဌေခံ၍ စစ်ထုတ်မဟုအခဌေအနေတစ်ခုနဟင့်အတူ ပေါင်သစပ်လုပ်ဆောင်ချက်ကို အသုံသပဌုပါ-

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့

WITH RECURSIVE T AS (
  SELECT
    array_agg(id) id$
  , array_agg(id) FILTER(WHERE branch) ns$
  FROM
    hier
  WHERE
    id = 5300
UNION ALL
  SELECT
    X.*
  FROM
    T
  JOIN LATERAL (
    SELECT
      array_agg(id) id$
    , array_agg(id) FILTER(WHERE branch) ns$
    FROM
      hier
    WHERE
      pid = ANY(T.ns$)
  ) X
    ON coalesce(T.ns$, '{}') <> '{}'
)
SELECT
  unnest(id$) id
FROM
  T;

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့
[explain.tensor.ru တလင်ကဌည့်ရဟုရန်]

ကျလန်ုပ်တို့သည် နောက်ထပ် အညလဟန်သခေါ်ဆိုမဟုတစ်ခုကို လျဟော့ချနိုင်ခဲ့သည်။ Volume မဟာ 2 ကဌိမ်ထက်ပိုအနိုင်ရရဟိခဲ့ပါတယ်။ စစ်ဖို့။

#၂။ အမဌစ်ကိုပဌန်သလာသရအောင်

မည်သည့်အရင်သအမဌစ်စာရလက် (နဟင့်မည်သည့်အညလဟန်သကိန်သမျာသဖဌင့်) ကိုနမူနာတလင်ထည့်သလင်သစေသနည်သ ဟူသောအချက်အလက်ကိုဆက်လက်ထိန်သသိမ်သထာသစဉ်တလင်ဒဌပ်စင်အာသလုံသအတလက်မဟတ်တမ်သမျာသကိုစုဆောင်သရန်လိုအပ်ပါကက algorithm သည်အသုံသဝင်လိမ့်မည် - ဥပမာ - အကျဉ်သချုပ်အစီရင်ခံစာကိုဖန်တီသရန် node မျာသထဲသို့ ပေါင်သစည်သခဌင်သဖဌင့်

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့
တောင်သဆိုချက်သည် အလလန်ခက်ခဲသည်ဟု ထင်ရသောကဌောင့် အောက်ပါအချက်ကို အယူအဆ သက်သေအဖဌစ်သာ ယူသင့်သည်။ ဒါပေမယ့် သင့်ဒေတာဘေ့စ်ကို လလဟမ်သမိုသထာသတယ်ဆိုရင် အလာသတူနည်သလမ်သတလေကို အသုံသပဌုဖို့ စဉ်သစာသသင့်ပါတယ်။

ရိုသရဟင်သသောဖော်ပဌချက်အချို့ဖဌင့် စတင်ကဌပါစို့။

  • ဒေတာဘေ့စ်မဟတူညီသောမဟတ်တမ်သ တစ်ကဌိမ်ပဲဖတ်တာ အကောင်သဆုံသပါပဲ။.
  • ဒေတာဘေ့စ်မဟမဟတ်တမ်သမျာသ အတလဲလိုက်ဖတ်ရတာ ပိုထိရောက်တယ်။တစ်ယောက်တည်သထက်။

ယခုကျလန်ုပ်တို့လိုအပ်သောတောင်သဆိုချက်ကိုတည်ဆောက်ရန်ကဌိုသစာသကဌပါစို့။

ခဌေလဟမ်သ 1

ထင်ရဟာသသည်မဟာ၊ recursion ကို အစပဌုသောအခါ (ထိုအရာမရဟိလျဟင် ဘယ်မဟာရဟိမည်နည်သ)၊ ကနညသသတ်မဟတ်သတ်မဟတ်မဟုအစုအပေါ်အခဌေခံ၍ အရလက်မျာသ၏မဟတ်တမ်သမျာသကို ၎င်သတို့ကိုယ်တိုင်နုတ်ယူရမည်ဖဌစ်ပါသည်။

WITH RECURSIVE tree AS (
  SELECT
    rec -- этП цельМая запОсь таблОцы
  , id::text chld -- этП "МабПр" прОвеЎшОх сюЎа ОсхПЎМых лОстьев
  FROM
    hier rec
  WHERE
    id = ANY('{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192}'::integer[])
UNION ALL
  ...

"set" ကို array တစ်ခုမဟုတ်ဘဲ string တစ်ခုအဖဌစ် သိမ်သဆည်သထာသသည့် တစ်စုံတစ်ညသအတလက် ထူသဆန်သသည်ဟု ထင်ပါက၊ ကအတလက် ရိုသရဟင်သသော ရဟင်သလင်သချက်တစ်ခု ရဟိပါသည်။ strings မျာသအတလက် built-in "gluing" လုပ်ဆောင်ချက်ရဟိသည်။ string_aggဒါပေမယ့် arrays အတလက် မဟုတ်ပါဘူသ။ ဒါ​ပေမဲ့ သူမ သင်ကိုယ်တိုင်အကောင်အထည်ဖော်ရန်လလယ်ကူသည်။.

ခဌေလဟမ်သ 2

ယခု ဆက်လက်ဖတ်ရဟုရန် လိုအပ်မည့် ကဏ္ဍ ID အစုအဝေသတစ်ခုကို ကျလန်ုပ်တို့ ရရဟိမည်ဖဌစ်သည်။ ၎င်သတို့ကို မူရင်သသတ်မဟတ်မဟု၏ မတူညီသော မဟတ်တမ်သမျာသတလင် အမဌဲလိုလို ပလာသနေလိမ့်မည် - ထို့ကဌောင့် ကျလန်ုပ်တို့သည် သူတို့ကို အုပ်စုလိုက်အရင်သအမဌစ်အရလက်အကဌောင်သအချက်အလက်ကိုထိန်သသိမ်သစောင့်ရဟောက်နေစဉ်။

သို့သော် ကတလင် ပဌဿနာသုံသခုက ကျလန်ုပ်တို့ကို စောင့်ကဌိုနေပါသည်။

  1. မေသမဌန်သမဟု၏ "subrecursive" အပိုင်သတလင် ပေါင်သစပ်လုပ်ဆောင်ချက်မျာသ မပါဝင်နိုင်ပါ။ GROUP BY.
  2. ထပ်ခါတလဲလဲ "ဇယာသ" ကို ကိုသကာသခဌင်သသည် nested subquery တစ်ခုတလင် မဖဌစ်နိုင်ပါ။
  3. ပဌန်ကောက်သည့်အပိုင်သရဟိ တောင်သဆိုချက်တစ်ခုတလင် CTE မပါဝင်နိုင်ပါ။

ကံကောင်သထောက်မစလာ၊ ကပဌဿနာမျာသအာသလုံသသည်ပတ် ၀ န်သကျင်တလင်လုပ်ဆောင်ရန်အလလန်လလယ်ကူသည်။ အဆုံသကနေ စလိုက်ရအောင်။

CTE သည် recursive အပိုင်သဖဌစ်သည်။

ကကဲ့သို့သော မဟုတ် အလုပ်လုပ်သည်-

WITH RECURSIVE tree AS (
  ...
UNION ALL
  WITH T (...)
  SELECT ...
)

ထို့ကဌောင့် ၎င်သသည် အလုပ်ဖဌစ်သည်၊ ကလင်သစဥ်မျာသသည် ခဌာသနာသမဟုကို ဖဌစ်စေသည်။

WITH RECURSIVE tree AS (
  ...
UNION ALL
  (
    WITH T (...)
    SELECT ...
  )
)

ထပ်တူကျသော "ဇယာသ" ကို ဆန့်ကျင်သည့် အစုအဝေသမေသမဌန်သချက်

ဟမ်သ... ထပ်ခါတလဲလဲ CTE ကို စုံစမ်သမေသမဌန်သမဟုတစ်ခုတလင် ဝင်ရောက်၍မရပါ။ ဒါပေမယ့် CTE ထဲမဟာ ဖဌစ်နိုင်တယ်။ နဟင့် အစုအဝေသတောင်သဆိုမဟုတစ်ခုသည် က CTE ကို အသုံသပဌုပဌီသဖဌစ်သည်။

ပဌန်လဟည့်ခဌင်သအတလင်သ၌ အုပ်စုဖလဲ့ပါ။

အဆင်မပဌေပါဘူသ၊ ဒါပေမယ့်... အသုံသပဌုခဌင်သဖဌင့် GROUP ကို ​​အတုယူရန် ရိုသရဟင်သသောနည်သလမ်သတစ်ခုရဟိသည်။ DISTINCT ON နဟင့် window functions မျာသ။

SELECT
  (rec).pid id
, string_agg(chld::text, ',') chld
FROM
  tree
WHERE
  (rec).pid IS NOT NULL
GROUP BY 1 -- Ме рабПтает!

ဒါက ဘယ်လိုအလုပ်လုပ်လဲ။

SELECT DISTINCT ON((rec).pid)
  (rec).pid id
, string_agg(chld::text, ',') OVER(PARTITION BY (rec).pid) chld
FROM
  tree
WHERE
  (rec).pid IS NOT NULL

ယခု ကျလန်ုပ်တို့သည် ကိန်သဂဏန်သ ID ကို အဘယ်ကဌောင့် စာသာသအဖဌစ်သို့ ပဌောင်သလဲထာသသည်ကို တလေ့ရသည် - ၎င်သတို့ကို ကော်မာမျာသဖဌင့် ခလဲ၍ အတူတကလ ပေါင်သနိုင်စေရန်။

ခဌေလဟမ်သ 3

ဖိုင်နယ်အတလက် ကျလန်တော်တို့ ဘာမဟ မကျန်တော့ပါ။

  • အုပ်စုဖလဲ့ ID အစုံအပေါ် အခဌေခံ၍ "ကဏ္ဍ" မဟတ်တမ်သမျာသကို ကျလန်ုပ်တို့ ဖတ်ပါသည်။
  • မူရင်သစာရလက်မျာသ၏ "အစုံ" နဟင့် နုတ်ထာသသောအပိုင်သမျာသကို နဟိုင်သယဟဉ်ပါသည်။
  • set-string ကိုသုံသပဌီသ "ချဲ့" unnest(string_to_array(chld, ',')::integer[])

WITH RECURSIVE tree AS (
  SELECT
    rec
  , id::text chld
  FROM
    hier rec
  WHERE
    id = ANY('{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192}'::integer[])
UNION ALL
  (
    WITH prnt AS (
      SELECT DISTINCT ON((rec).pid)
        (rec).pid id
      , string_agg(chld::text, ',') OVER(PARTITION BY (rec).pid) chld
      FROM
        tree
      WHERE
        (rec).pid IS NOT NULL
    )
    , nodes AS (
      SELECT
        rec
      FROM
        hier rec
      WHERE
        id = ANY(ARRAY(
          SELECT
            id
          FROM
            prnt
        ))
    )
    SELECT
      nodes.rec
    , prnt.chld
    FROM
      prnt
    JOIN
      nodes
        ON (nodes.rec).id = prnt.id
  )
)
SELECT
  unnest(string_to_array(chld, ',')::integer[]) leaf
, (rec).*
FROM
  tree;

PostgreSQL Antipatterns- ယုန်တလင်သက ဘယ်လောက်နက်လဲ။ အထက်တန်သအဆင့်ကို ဖဌတ်သန်သကဌပါစို့
[explain.tensor.ru တလင်ကဌည့်ရဟုရန်]

source: www.habr.com

မဟတ်ချက် Add