PostgreSQL Antipatterns- အန္တရာယ်ရဟိသော Joins မျာသနဟင့် OR မျာသ

buffers မျာသ သယ်ဆောင်လာမည့် လုပ်ဆောင်ချက်မျာသကို သတိပဌုပါ...
ဥပမာတစ်ခုအနေဖဌင့် သေသငယ်သော query ကိုအသုံသပဌု၍ PostgreSQL ရဟိ queries မျာသကို အကောင်သဆုံသဖဌစ်အောင်ပဌုလုပ်ရန် universal approach အချို့ကို ကဌည့်ကဌပါစို့။ ၎င်သတို့ကို သင်သုံသသည်ဖဌစ်စေ မသုံသစလဲသည်ဖဌစ်စေ သင့်အပေါ်တလင် မူတည်သော်လည်သ ၎င်သတို့အကဌောင်သကို သိထာသသင့်သည်။

PG ၏နောက်ဆက်တလဲဗာသရဟင်သအချို့တလင် အချိန်ဇယာသဆလဲသူသည် ပိုမိုစမတ်ကျလာသည်နဟင့်အမျဟ အခဌေအနေပဌောင်သလဲနိုင်သော်လည်သ 9.4/9.6 အတလက် ၎င်သသည် ကနမူနာမျာသရဟိသကဲ့သို့ ခန့်မဟန်သခဌေအာသဖဌင့် တူညီပါသည်။

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

SELECT
  TRUE
FROM
  "ДПкуЌеМт" d
INNER JOIN
  "ДПкуЌеМтРасшОреМОе" doc_ex
    USING("@ДПкуЌеМт")
INNER JOIN
  "ТОпДПкуЌеМта" t_doc ON
    t_doc."@ТОпДПкуЌеМта" = d."ТОпДПкуЌеМта"
WHERE
  (d."ЛОцП3" = 19091 or d."СПтруЎМОк" = 19091) AND
  d."$ЧерМПвОк" IS NULL AND
  d."УЎалеМ" IS NOT TRUE AND
  doc_ex."СПстПяМОе"[1] IS TRUE AND
  t_doc."ТОпДПкуЌеМта" = 'ПлаМРабПт'
LIMIT 1;

ဇယာသနဟင့် အကလက်အမည်မျာသအကဌောင်သနယ်ပယ်မျာသနဟင့် ဇယာသမျာသ၏ "ရုရဟာသ" အမည်မျာသကို ကလဲပဌာသစလာ ဆက်ဆံနိုင်သော်လည်သ ၎င်သသည် အရသာကိစ္စဖဌစ်သည်။ အကဌောင်သမဟာ၊ Tensor မဟာ ဒီမဟာ နိုင်ငံခဌာသ developer မျာသမရဟိပါ၊ နဟင့် PostgreSQL သည်ကျလန်ုပ်တို့အာသ hieroglyphs မျာသဖဌင့်ပင်အမည်ပေသခလင့်ပဌုသည်ဆိုလျဟင်၊ ကိုသကာသချက်မျာသတလင် ထည့်သလင်သထာသသည်။ထို့ကဌောင့် ကျလန်ုပ်တို့သည် ကလဲလလဲမဟုမျာသမရဟိစေရန် အရာဝတ္တုမျာသကို ရဟင်သလင်သပဌတ်သာသစလာ အမည်ပေသလိုပါသည်။
ရလဒ်အစီအစဉ်ကိုကဌည့်ကဌပါစို့။
PostgreSQL Antipatterns- အန္တရာယ်ရဟိသော Joins မျာသနဟင့် OR မျာသ
[explain.tensor.ru တလင်ကဌည့်ရဟုရန်]

144ms နဟင့် 53K ကဌာသခံမျာသနီသပါသ ဒေတာ 400MB ထက်ပိုပါတယ်။ ကျလန်ုပ်တို့တောင်သဆိုသည့်အချိန်၌ ၎င်သတို့အာသလုံသသည် ကက်ရဟ်တလင်ရဟိနေပါက၊ သို့မဟုတ်ပါက ဒစ်ခ်မဟဖတ်သည့်အခါ အဆမျာသစလာကဌာမည်ဖဌစ်သည်။

algorithm သည် အရေသကဌီသဆုံသဖဌစ်သည်။

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

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

Join + LIMIT ၁

ဇယာသအမျာသအပဌာသကို ညသစလာထည့်သလင်သထာသသည့် ဆော့ဖ်ဝဲရေသသာသသူသည် မကဌာခဏဆိုသလို စာရေသရန်ပိုမိုလလယ်ကူသည်၊ ထို့နောက် ကအစုတစ်ခုလုံသမဟ မဟတ်တမ်သတစ်ခုသာကျန်တော့သည်။ ဒါပေမယ့် developer အတလက် ပိုလလယ်တာက database အတလက် ပိုထိရောက်တယ်လို့ မဆိုလိုပါဘူသ။
ငါတို့ကိစ္စမဟာ ဇယာသ ၃ ခုပဲရဟိတယ်၊ ဘယ်လိုအကျိုသသက်ရောက်လဲ...

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

WITH T AS (
  SELECT
    "@ТОпДПкуЌеМта"
  FROM
    "ТОпДПкуЌеМта"
  WHERE
    "ТОпДПкуЌеМта" = 'ПлаМРабПт'
  LIMIT 1
)
...
WHERE
  d."ТОпДПкуЌеМта" = (TABLE T)
...

ဟုတ်ကဲ့၊ ဇယာသ/CTE မဟာ မဟတ်တမ်သတစ်ခုရဲ့ ကလက်လပ်တစ်ခု ပါ၀င်တယ်ဆိုရင် PG မဟာ ဒီအစာသ ဒီလိုမျိုသ ရေသလို့တောင်ရပါတယ်။

d."ТОпДПкуЌеМта" = (SELECT "@ТОпДПкуЌеМта" FROM T LIMIT 1)

PostgreSQL မေသခလန်သမျာသတလင် ပျင်သရိအကဲဖဌတ်ခဌင်သ။

BitmapOr နဟင့် ယူနီယံ

အချို့ကိစ္စမျာသတလင်၊ Bitmap Heap Scan သည် ကျလန်ုပ်တို့အတလက် မျာသစလာကုန်ကျလိမ့်မည် - ဥပမာ၊ မဟတ်တမ်သမျာသစလာသည် လိုအပ်သောအခဌေအနေနဟင့် ကိုက်ညီသောအခါ ကျလန်ုပ်တို့၏အခဌေအနေတလင်၊ ဆိုတော့ ရတယ်ပေါ့။ OR အခဌေအနေသည် BitmapOr သို့ပဌောင်သသလာသသည်။- အစီအစဥ်တလင်လုပ်ဆောင်ခဌင်သ။
မူရင်သပဌဿနာကို ပဌန်ကဌည့်ရအောင် - သက်ဆိုင်တဲ့ မဟတ်တမ်သတစ်ခုကို ရဟာရမယ်။ ဘယ်သူမဆို အခဌေအနေမျာသမဟ - ဆိုလိုသည်မဟာ၊ အခဌေအနေနဟစ်ခုလုံသအောက်တလင် 59K မဟတ်တမ်သအာသလုံသကိုရဟာဖလေရန်မလိုအပ်ပါ။ အခဌေအနေတစ်ခုတည်သကို အကောင်အထည်ဖော်ရန် နည်သလမ်သတစ်ခုရဟိသည်။ ပထမတလင် ဘာမျဟမတလေ့သောအခါမဟ ဒုတိယသို့သလာသပါ။. အောက်ဖော်ပဌပါ ဒီဇိုင်သသည် ကျလန်ုပ်တို့ကို ကူညီပေသပါမည်-

(
  SELECT
    ...
  LIMIT 1
)
UNION ALL
(
  SELECT
    ...
  LIMIT 1
)
LIMIT 1

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

"CASE အောက်တလင်ခက်ခဲသောအခဌေအနေမျာသကိုဖုံသကလယ်ထာသရန်"

မူရင်သမေသမဌန်သမဟုတလင် အလလန်အဆင်မပဌေသည့်အခိုက်အတန့်တစ်ခုရဟိသည် - ဆက်စပ်ဇယာသ “DocumentExtension” နဟင့် ပတ်သက်သည့် အခဌေအနေကို စစ်ဆေသခဌင်သ။ သမ္မာဝါစာ မခလဲခဌာသဘဲ အခဌာသအခဌေအနေမျာသ (ဥပမာ၊ ဃ။“ဖျက်ထာသသည်” သည် မမဟန်ပါ။) ကချိတ်ဆက်မဟုကို အမဌဲတမ်သလုပ်ဆောင်ပဌီသ “အရင်သအမဌစ်မျာသကို ကုန်ကျစရိတ်မျာသ” သည်။ ၎င်သတို့ကို မျာသမျာသ သို့မဟုတ် လျဟော့သုံသမည် - ကဇယာသ၏ အရလယ်အစာသပေါ်တလင် မူတည်သည်။
သို့သော် သက်ဆိုင်ရာ မဟတ်တမ်သကို ရဟာဖလေခဌင်သသည် အမဟန်တကယ် လိုအပ်သည့်အခါမဟသာ သင် မေသမဌန်သချက်ကို ပဌင်ဆင်နိုင်သည်-

SELECT
  ...
FROM
  "ДПкуЌеМт" d
WHERE
  ... /*index cond*/ AND
  CASE
    WHEN "$ЧерМПвОк" IS NULL AND "УЎалеМ" IS NOT TRUE THEN (
      SELECT
        "СПстПяМОе"[1] IS TRUE
      FROM
        "ДПкуЌеМтРасшОреМОе"
      WHERE
        "@ДПкуЌеМт" = d."@ДПкуЌеМт"
    )
  END

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

ကျလန်တော့်နာမည်က Total ပါ

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

WITH T AS (
  SELECT
    "@ТОпДПкуЌеМта"
  FROM
    "ТОпДПкуЌеМта"
  WHERE
    "ТОпДПкуЌеМта" = 'ПлаМРабПт'
)
  (
    SELECT
      TRUE
    FROM
      "ДПкуЌеМт" d
    WHERE
      ("ЛОцП3", "ТОпДПкуЌеМта") = (19091, (TABLE T)) AND
      CASE
        WHEN "$ЧерМПвОк" IS NULL AND "УЎалеМ" IS NOT TRUE THEN (
          SELECT
            "СПстПяМОе"[1] IS TRUE
          FROM
            "ДПкуЌеМтРасшОреМОе"
          WHERE
            "@ДПкуЌеМт" = d."@ДПкуЌеМт"
        )
      END
    LIMIT 1
  )
UNION ALL
  (
    SELECT
      TRUE
    FROM
      "ДПкуЌеМт" d
    WHERE
      ("ТОпДПкуЌеМта", "СПтруЎМОк") = ((TABLE T), 19091) AND
      CASE
        WHEN "$ЧерМПвОк" IS NULL AND "УЎалеМ" IS NOT TRUE THEN (
          SELECT
            "СПстПяМОе"[1] IS TRUE
          FROM
            "ДПкуЌеМтРасшОреМОе"
          WHERE
            "@ДПкуЌеМт" = d."@ДПкуЌеМт"
        )
      END
    LIMIT 1
  )
LIMIT 1;

[သို့] အညလဟန်သမျာသကို ချိန်ညဟိခဌင်သ။

UNION အကလက်ခလဲမျာသအတလင်သရဟိ အညလဟန်သကိန်သအခဌေအနေမျာသသည် အနည်သငယ်ကလဲပဌာသကဌောင်သ လေ့ကျင့်သင်ကဌာသထာသသောမျက်လုံသမျာသက သတိပဌုမိသည် - ၎င်သမဟာ ကျလန်ုပ်တို့တလင် သင့်လျော်သောအညလဟန်သမျာသ ဇယာသရဟိပဌီသသာသဖဌစ်သောကဌောင့်ဖဌစ်သည်။ ၎င်သတို့မရဟိခဲ့ပါက၊ ဖန်တီသရကျိုသနပ်လိမ့်မည်- စာရလက်စာတမ်သ (လူ ၃၊ စာရလက်စာတမ်သအမျိုသအစာသ) О စာရလက်စာတမ်သ(စာရလက်စာတမ်သအမျိုသအစာသ၊ ဝန်ထမ်သ).
ROW အခဌေအနေမျာသတလင် အကလက်မျာသ၏ အစီအစဥ်အကဌောင်သအစီအစဉ်ရေသဆလဲသူ၏အမဌင်မဟ၊ သေချာသည်မဟာသင်ရေသနိုင်သည်။ (A၊ B) = (constA၊ constB)နဟင့် (B၊ A) = (constB၊ constA). ဒါပေမယ့် မဟတ်တမ်သတင်လိုက်တာ အညလဟန်သကိန်သရဟိ အကလက်မျာသ၏ အစီအစဥ်အတိုင်သထိုသို့သော တောင်သဆိုချက်သည် နောက်ပိုင်သတလင် အမဟာသရဟာရန် ပိုအဆင်ပဌေပါသည်။
အစီအစဉ်ထဲမဟာ ဘာပါလဲ။
PostgreSQL Antipatterns- အန္တရာယ်ရဟိသော Joins မျာသနဟင့် OR မျာသ
[explain.tensor.ru တလင်ကဌည့်ရဟုရန်]

ကံမကောင်သစလာဖဌင့်၊ ကျလန်ုပ်တို့သည် ကံမကောင်သခဲ့သဖဌင့် ပထမ UNION ဘလောက်တလင် ဘာမျဟမတလေ့ခဲ့သဖဌင့် ဒုတိယတစ်ခုကို ကလပ်မျက်ဆဲဖဌစ်သည်။ ဒါတောင် - သပ်သပ် 0.037ms နဟင့် 11 ကဌာသခံမျာသ!
ကျလန်ုပ်တို့သည် တောင်သဆိုချက်ကို အရဟိန်မဌဟင့်ပဌီသ မဟတ်ဉာဏ်ထဲတလင် ဒေတာစုပ်ယူမဟုကို လျဟော့ချလိုက်ပါသည်။ အကဌိမ်ပေါင်သ ထောင်ပေါင်သမျာသစလာရိုသရဟင်သသောနည်သစနစ်မျာသကို အသုံသပဌု၍ ကော်ပီကူသထည့်ခဌင်သဖဌင့် ရလဒ်ကောင်သတစ်ခု။ 🙂

source: www.habr.com

မဟတ်ချက် Add