EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

සංවර්ධකයෙකු ඔහුගේ DBA වෙත ගෙන එන සම්භාව්‍ය ප්‍රශ්නය හෝ ව්‍යාපාර හිමිකරුවෙකු PostgreSQL උපදේශකයෙකු වෙත ගෙන එන සම්භාව්‍ය ප්‍රශ්නය සෑම විටම පාහේ සමාන වේ: "ඉල්ලීම් දත්ත ගබඩාවේ සම්පූර්ණ වීමට මෙතරම් කාලයක් ගත වන්නේ ඇයි?"

සාම්ප්‍රදායික හේතු සමූහය:

  • අකාර්යක්ෂම ඇල්ගොරිතම
    ඔබ වාර්තා දස දහස් ගණනකට වඩා CTE කිහිපයකට සම්බන්ධ වීමට තීරණය කරන විට
  • අදාළ නොවන සංඛ්යා ලේඛන
    වගුවේ ඇති දත්තවල සත්‍ය බෙදාහැරීම දැනටමත් අවසන් වරට ANALYZE විසින් එකතු කරන ලද එකට වඩා බෙහෙවින් වෙනස් නම්
  • සම්පත් මත "ප්ලග්"
    සහ තවදුරටත් CPU හි ප්‍රමාණවත් කැපවූ පරිගණක බලයක් නොමැත, ගිගාබයිට් මතකයක් නිරන්තරයෙන් පොම්ප කරනු ලැබේ, නැතහොත් තැටියට දත්ත සමුදායේ සියලුම “අවශ්‍යතා” සමඟ තබා ගත නොහැක.
  • අවහිර කිරීම තරඟකාරී ක්‍රියාවලි වලින්

අවහිර කිරීම් අල්ලා ගැනීම සහ විශ්ලේෂණය කිරීම තරමක් අපහසු නම්, අපට අවශ්‍ය අනෙක් සියල්ල සඳහා විමසුම් සැලැස්ම, භාවිතයෙන් ලබා ගත හැක ක්‍රියාකරු පැහැදිලි කරන්න (ඇත්ත වශයෙන්ම, වහාම පැහැදිලි කිරීම වඩා හොඳය (විශ්ලේෂණය, බෆර) ...) හෝ auto_explain මොඩියුලය.

එහෙත්, එම ලේඛනයේ සඳහන් පරිදි,

"සැලැස්මක් අවබෝධ කර ගැනීම කලාවක් වන අතර එය ප්‍රගුණ කිරීමට යම් අත්දැකීමක් අවශ්‍ය වේ..."

නමුත් ඔබ නිවැරදි මෙවලම භාවිතා කරන්නේ නම් ඔබට එය නොමැතිව කළ හැකිය!

විමසුම් සැලැස්මක් සාමාන්‍යයෙන් පෙනෙන්නේ කෙසේද? ඒ වගේ දෙයක්:

Index Scan using pg_class_relname_nsp_index on pg_class (actual time=0.049..0.050 rows=1 loops=1)
  Index Cond: (relname = $1)
  Filter: (oid = $0)
  Buffers: shared hit=4
  InitPlan 1 (returns $0,$1)
    ->  Limit (actual time=0.019..0.020 rows=1 loops=1)
          Buffers: shared hit=1
          ->  Seq Scan on pg_class pg_class_1 (actual time=0.015..0.015 rows=1 loops=1)
                Filter: (relkind = 'r'::"char")
                Rows Removed by Filter: 5
                Buffers: shared hit=1

හෝ මේ වගේ:

"Append  (cost=868.60..878.95 rows=2 width=233) (actual time=0.024..0.144 rows=2 loops=1)"
"  Buffers: shared hit=3"
"  CTE cl"
"    ->  Seq Scan on pg_class  (cost=0.00..868.60 rows=9972 width=537) (actual time=0.016..0.042 rows=101 loops=1)"
"          Buffers: shared hit=3"
"  ->  Limit  (cost=0.00..0.10 rows=1 width=233) (actual time=0.023..0.024 rows=1 loops=1)"
"        Buffers: shared hit=1"
"        ->  CTE Scan on cl  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.021..0.021 rows=1 loops=1)"
"              Buffers: shared hit=1"
"  ->  Limit  (cost=10.00..10.10 rows=1 width=233) (actual time=0.117..0.118 rows=1 loops=1)"
"        Buffers: shared hit=2"
"        ->  CTE Scan on cl cl_1  (cost=0.00..997.20 rows=9972 width=233) (actual time=0.001..0.104 rows=101 loops=1)"
"              Buffers: shared hit=2"
"Planning Time: 0.634 ms"
"Execution Time: 0.248 ms"

නමුත් “පත්‍රයෙන්” පෙළෙහි සැලැස්ම කියවීම ඉතා අපහසු සහ අපැහැදිලි ය:

  • නෝඩයේ දර්ශනය වේ උපස්ථර සම්පත් මගින් එකතුව
    එනම්, විශේෂිත නෝඩයක් ක්‍රියාත්මක කිරීමට කොපමණ කාලයක් ගත වූවාද, නැතහොත් මේසයෙන් මෙම කියවීම තැටියෙන් දත්ත ගෙන ආවේ කොපමණ දැයි තේරුම් ගැනීමට, ඔබ කෙසේ හෝ එකක් අනෙකෙන් අඩු කළ යුතුය.
  • node කාලය අවශ්ය වේ ලූප මගින් ගුණ කරන්න
    ඔව්, අඩු කිරීම යනු "හිසෙහි" සිදු කළ යුතු වඩාත්ම සංකීර්ණ මෙහෙයුම නොවේ - සියල්ලට පසු, ක්රියාත්මක කිරීමේ කාලය නෝඩයක් ක්රියාත්මක කිරීම සඳහා සාමාන්යය ලෙස දක්වා ඇති අතර, ඒවා සිය ගණනක් විය හැකිය
  • හොඳයි, මේ සියල්ල එක්ව ප්‍රධාන ප්‍රශ්නයට පිළිතුරු දීමෙන් අපව වළක්වයි - ඉතින් කවුද "දුර්වලම සම්බන්ධකය"?

අපි මේ සියල්ල අපගේ සංවර්ධකයින් සිය ගණනකට පැහැදිලි කිරීමට උත්සාහ කළ විට, පිටතින් එය මේ වගේ දෙයක් බව අපට වැටහුණි:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

ඒ කියන්නේ අපිට ඕනේ...

මෙවලම

එය තුළ අපි සැලැස්ම සහ ඉල්ලීම අනුව "දොස් පැවරිය යුත්තේ කාටද සහ කුමක් කළ යුතුද" යන්න තේරුම් ගැනීමට උපකාර වන සියලුම ප්රධාන යාන්ත්රිකයන් එකතු කිරීමට උත්සාහ කළෙමු. හොඳයි, ඔබේ අත්දැකීමෙන් කොටසක් ප්‍රජාව සමඟ බෙදා ගන්න.
හමු වී භාවිතා කරන්න - පැහැදිලි කරන්න.tensor.ru

සැලසුම්වල දෘශ්‍යතාව

මෙහෙම බැලුවම සැලැස්ම තේරුම් ගන්න ලේසිද?

Seq Scan on pg_class (actual time=0.009..1.304 rows=6609 loops=1)
  Buffers: shared hit=263
Planning Time: 0.108 ms
Execution Time: 1.800 ms

ඇත්තටම නැහැ.

නමුත් මේ වගේ, සංක්ෂිප්ත ස්වරූපයෙන්ප්රධාන දර්ශක වෙන් කරන විට, එය වඩාත් පැහැදිලි වේ:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

නමුත් සැලැස්ම වඩාත් සංකීර්ණ නම්, ඔහු ගලවා ගැනීමට පැමිණෙනු ඇත piechart කාලය බෙදා හැරීම නෝඩ් මගින්:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

හොඳයි, වඩාත්ම දුෂ්කර විකල්ප සඳහා ඔහු උදව් කිරීමට ඉක්මන් වේ ප්රගති සටහන:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

උදාහරණයක් ලෙස, සැලැස්මකට සත්‍ය මූල එකකට වඩා තිබිය හැකි ඉතා සුළු නොවන අවස්ථා තිබේ:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේදEXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

ව්යුහාත්මක ඉඟි

හොඳයි, සැලැස්මේ සම්පූර්ණ ව්‍යුහය සහ එහි වේදනාකාරී ස්ථාන දැනටමත් සකස් කර තිබේ නම්, ඒවා සංවර්ධකයාට ඉස්මතු කර “රුසියානු භාෂාවෙන්” පැහැදිලි නොකරන්නේ මන්ද?

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේදඅපි දැනටමත් එවැනි නිර්දේශ ආකෘති දුසිම් කිහිපයක් එකතු කර ඇත.

පේළියෙන් පේළි විමසුම් පැතිකඩ

දැන්, ඔබ මුල් විමසුම විශ්ලේෂණය කළ සැලැස්මට අධිස්ථාපනය කළහොත්, එක් එක් ප්‍රකාශය සඳහා කොපමණ කාලයක් වැය කර ඇත්දැයි ඔබට දැක ගත හැකිය - මෙවැනි දෙයක්:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

...හෝ මේ වගේ:

EXPLAIN නිශ්ශබ්ද වන්නේ කුමක්ද සහ එය කතා කර ගන්නේ කෙසේද

ඉල්ලීමකට පරාමිති ආදේශ කිරීම

ඔබ සැලැස්මට ඉල්ලීමක් පමණක් නොව, ලොගයේ DETAIL රේඛාවෙන් එහි පරාමිතීන් "අමුණා" නම්, ඔබට එය එක් විකල්පයකින් අතිරේකව පිටපත් කළ හැකිය:

  • විමසුමේ අගය ආදේශනය සමඟ
    ඔබේ පදනම මත සෘජුව ක්‍රියාත්මක කිරීම සහ වැඩිදුර පැතිකඩ සඳහා

    SELECT 'const', 'param'::text;
  • PREPARE/EXECUTE හරහා අගය ආදේශනය සමඟ
    උපලේඛකයාගේ කාර්යය අනුකරණය කිරීමට, පරාමිතික කොටස නොසලකා හැරිය හැකි විට - උදාහරණයක් ලෙස, කොටස් කළ වගු මත වැඩ කරන විට

    DEALLOCATE ALL;
    PREPARE q(text) AS SELECT 'const', $1::text;
    EXECUTE q('param'::text);
    

සැලසුම් ලේඛනාගාරය

සගයන් සමඟ අලවන්න, විශ්ලේෂණය කරන්න, බෙදාගන්න! සැලසුම් සංරක්ෂිතව පවතිනු ඇති අතර ඔබට පසුව ඒවා වෙත ආපසු යා හැක: පැහැදිලි කරන්න.tensor.ru/archive

නමුත් ඔබේ සැලැස්ම අන් අය දැකීමට ඔබට අවශ්‍ය නැතිනම්, "සංරක්ෂිතයේ ප්‍රකාශනය නොකරන්න" කොටුව සලකුණු කිරීමට අමතක නොකරන්න.

සැලැස්මක් විශ්ලේෂණය කිරීමේදී ඇතිවන දුෂ්කරතා සහ තීරණ ගැන මම පහත ලිපි වලින් කතා කරමි.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න