ما الذي يشرحه PostgreSQL ليخبرني بالضبط؟

StackOverflow https://stackoverflow.com/questions/117262

  •  02-07-2019
  •  | 
  •  

سؤال

إن مخرجات شرح MySQL واضحة جدًا.يعد PostgreSQL أكثر تعقيدًا بعض الشيء.ولم أتمكن من العثور على مورد جيد يشرح ذلك أيضًا.

هل يمكنك وصف ما يقوله بالضبط أو على الأقل توجيهي نحو مصدر جيد؟

هل كانت مفيدة؟

المحلول

شرح_EXPLAIN.pdf يمكن أن يساعد أيضا.

نصائح أخرى

الجزء الذي أجده دائمًا مربكًا هو تكلفة بدء التشغيل مقابل التكلفة الإجمالية.أبحث في Google عن هذا في كل مرة أنساها، وهو ما يعيدني إلى هنا، وهو ما لا يفسر الفرق، ولهذا أكتب هذه الإجابة.وهذا ما استخلصته من بوستجرس EXPLAIN توثيق, وأوضح كما أفهم ذلك.

فيما يلي مثال من أحد التطبيقات التي تدير المنتدى:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

إليك الشرح الرسومي من PgAdmin:

graphical explanation of first query

(عند استخدام PgAdmin، يمكنك توجيه الماوس نحو أحد المكونات لقراءة تفاصيل التكلفة.)

يتم تمثيل التكلفة كصف، على سبيل المثال.تكلفة LIMIT يكون cost=0.00..3.39 وتكلفة المسح التسلسلي post يكون cost=0.00..15629.12.الرقم الأول في الصف هو التكلفة البدائية والرقم الثاني هو التكلفة الإجمالية.لأنني استخدمت EXPLAIN و لا EXPLAIN ANALYZE, هذه التكاليف هي تقديرات وليست مقاييس فعلية.

  • التكلفة البدائية هو مفهوم صعب.إنه لا يمثل فقط مقدار الوقت قبل هذا المكون يبدأ.وهو يمثل مقدار الوقت بين وقت بدء تنفيذ المكون (القراءة في البيانات) ومتى يقوم المكون بإخراج صفه الأول.
  • التكلفة الإجمالية هو وقت التنفيذ الكامل للمكون، منذ أن يبدأ في قراءة البيانات حتى ينتهي من كتابة مخرجاته.

ومما يزيد الأمر تعقيدًا، أن تكاليف كل عقدة "أصلية" تتضمن تكلفة العقد الفرعية الخاصة بها.في تمثيل النص، يتم تمثيل الشجرة بمسافة بادئة، على سبيل المثال. LIMIT هي العقدة الأم و Seq Scan هو طفلها.في تمثيل PgAdmin، تشير الأسهم من الطفل إلى الأصل - اتجاه تدفق البيانات - وهو ما قد يكون غير بديهي إذا كنت معتادًا على نظرية الرسم البياني.

تشير الوثائق إلى أن التكاليف تشمل كافة العقد الفرعية، ولكن لاحظ أن التكلفة الإجمالية للأصل 3.39 أصغر بكثير من التكلفة الإجمالية للطفل 15629.12.التكلفة الإجمالية ليست شاملة لأن مكونًا مثل LIMIT لا تحتاج إلى معالجة مدخلاتها بالكامل.انظر EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; مثال في بوستجرس EXPLAIN توثيق.

في المثال أعلاه، وقت بدء التشغيل هو صفر لكلا المكونين، لأنه لا يحتاج أي مكون إلى إجراء أي معالجة قبل أن يبدأ في كتابة الصفوف:يقوم المسح المتسلسل بقراءة الصف الأول من الجدول وإصداره.ال LIMIT يقرأ الصف الأول ثم يطلقه.

متى يحتاج المكون إلى إجراء الكثير من المعالجة قبل أن يتمكن من البدء في إخراج أي صفوف؟هناك الكثير من الأسباب المحتملة، ولكن دعونا نلقي نظرة على مثال واحد واضح.إليك نفس الاستعلام من قبل ولكنه يحتوي الآن على ملف ORDER BY بند:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

و بيانيا:

graphical explanation of second query

مرة أخرى، يتم تشغيل الفحص التسلسلي post ليس لديه تكلفة بدء التشغيل:يبدأ في إخراج الصفوف على الفور.لكن هذا النوع له تكلفة بدء تشغيل كبيرة 23283.24 لأنه يجب عليه ذلك قم بفرز الجدول بأكمله قبل أن يتمكن من إخراج صف واحد.التكلفة الإجمالية لهذا النوع 23859.27 أعلى قليلاً من تكلفة بدء التشغيل، مما يعكس حقيقة أنه بمجرد فرز مجموعة البيانات بأكملها، يمكن أن تنبعث البيانات التي تم فرزها بسرعة كبيرة.

لاحظ أن وقت بدء تشغيل LIMIT 23283.24 يساوي تمامًا وقت بدء النوع.هذا ليس بسبب LIMIT نفسها لديها وقت بدء تشغيل مرتفع.في الواقع، لا يوجد وقت لبدء التشغيل بمفرده، ولكن EXPLAIN يقوم بجمع كافة تكاليف الطفل لكل والد، وبالتالي فإن LIMIT يشمل وقت بدء التشغيل مجموع أوقات بدء التشغيل لأطفاله.

قد يؤدي تراكم التكاليف هذا إلى صعوبة فهم تكلفة تنفيذ كل مكون على حدة.على سبيل المثال، لدينا LIMIT ليس لديه وقت بدء تشغيل، ولكن هذا ليس واضحًا للوهلة الأولى.لهذا السبب، تم ربط العديد من الأشخاص الآخرين بـ Depesz.com, ، أداة أنشأها Hubert Lubaczewski (المعروف أيضًا باسم.depesz) الذي يساعد على الفهم EXPLAIN من خلال - من بين أمور أخرى - طرح تكاليف الأطفال من تكاليف الوالدين.ويذكر بعض التعقيدات الأخرى في تدوينة قصيرة عن أداته.

يتم تنفيذه من الأكثر مسافة بادئة إلى الأقل مسافة بادئة، وأعتقد أنه من أسفل الخطة إلى الأعلى.(إذا كان هناك قسمان بمسافة بادئة، يتم تنفيذ الجزء الموجود في أسفل الصفحة أولاً، ثم عندما يلتقيان يتم تنفيذ القسم الآخر، ثم يتم تنفيذ القاعدة التي تربطهما.)

الفكرة هي أنه في كل خطوة هناك مجموعة أو مجموعتان من البيانات التي تصل وتتم معالجتها وفقًا لبعض القواعد.إذا كانت هناك مجموعة بيانات واحدة فقط، فسيتم إجراء هذه العملية على مجموعة البيانات تلك.(على سبيل المثال، قم بمسح فهرس لمعرفة الصفوف التي تريدها، أو قم بتصفية مجموعة بيانات، أو فرزها.) إذا كان هناك اثنتين، فإن مجموعتي البيانات هما الشيئان اللذان تم وضع مسافة بادئة لهما بشكل أكبر، ويتم ضمهما بواسطة القاعدة التي تراها.يمكن تخمين معنى معظم القواعد بسهولة معقولة (خاصة إذا كنت قد قرأت مجموعة من الخطط التوضيحية من قبل)، ومع ذلك يمكنك محاولة التحقق من العناصر الفردية إما عن طريق البحث في الوثائق أو (أسهل) بمجرد إدخال العبارة في جوجل مع بعض الكلمات الرئيسية مثل EXPLAIN.

من الواضح أن هذا ليس شرحًا كاملاً، ولكنه يوفر سياقًا كافيًا يمكنك عادةً معرفة ما تريد.على سبيل المثال، فكر في هذه الخطة من قاعدة بيانات فعلية:

explain analyze
select a.attributeid, a.attributevalue, b.productid
from orderitemattribute a, orderitem b
where a.orderid = b.orderid
and a.attributeid = 'display-album'
and b.productid = 'ModernBook';

------------------------------------------------------------------------------------------------------------------------------------------------------------

 Merge Join  (cost=125379.14..125775.12 rows=3311 width=29) (actual time=841.478..841.478 rows=0 loops=1)
   Merge Cond: (a.orderid = b.orderid)
   ->  Sort  (cost=109737.32..109881.89 rows=57828 width=23) (actual time=736.163..774.475 rows=16815 loops=1)
         Sort Key: a.orderid
         Sort Method:  quicksort  Memory: 1695kB
         ->  Bitmap Heap Scan on orderitemattribute a  (cost=1286.88..105163.27 rows=57828 width=23) (actual time=41.536..612.731 rows=16815 loops=1)
               Recheck Cond: ((attributeid)::text = 'display-album'::text)
               ->  Bitmap Index Scan on (cost=0.00..1272.43 rows=57828 width=0) (actual time=25.033..25.033 rows=16815 loops=1)
                     Index Cond: ((attributeid)::text = 'display-album'::text)
   ->  Sort  (cost=15641.81..15678.73 rows=14769 width=14) (actual time=14.471..16.898 rows=1109 loops=1)
         Sort Key: b.orderid
         Sort Method:  quicksort  Memory: 76kB
         ->  Bitmap Heap Scan on orderitem b  (cost=310.96..14619.03 rows=14769 width=14) (actual time=1.865..8.480 rows=1114 loops=1)
               Recheck Cond: ((productid)::text = 'ModernBook'::text)
               ->  Bitmap Index Scan on id_orderitem_productid  (cost=0.00..307.27 rows=14769 width=0) (actual time=1.431..1.431 rows=1114 loops=1)
                     Index Cond: ((productid)::text = 'ModernBook'::text)
 Total runtime: 842.134 ms
(17 rows)

حاول قراءتها بنفسك ومعرفة ما إذا كان ذلك منطقيًا.

ما قرأته هو أن قاعدة البيانات تقوم أولاً بمسح ملف id_orderitem_productid Index، وذلك باستخدامه للعثور على الصفوف التي يريدها orderitem, ، ثم يقوم بفرز مجموعة البيانات هذه باستخدام الفرز السريع (سيتغير الفرز المستخدم إذا لم تتناسب البيانات مع ذاكرة الوصول العشوائي)، ثم يضع ذلك جانبًا.

بعد ذلك، يقوم بالمسح orditematt_attributeid_idx للعثور على الصفوف التي يريدها orderitemattribute ثم يقوم بفرز مجموعة البيانات هذه باستخدام الفرز السريع.

ثم يأخذ مجموعتي البيانات ويدمجهما.(إن صلة الدمج هي نوع من عملية "الضغط" حيث تسير مجموعتي البيانات المصنفتين بالتوازي، وتصدر الصف المرتبط عند تطابقهما.)

كما قلت، عليك العمل من خلال الجزء الداخلي للخطة إلى الجزء الخارجي، ومن الأسفل إلى الأعلى.

هناك أداة مساعدة متاحة عبر الإنترنت أيضًا، ديبيسز, ، والتي سوف تسلط الضوء على الأجزاء الباهظة الثمن من نتائج التحليل.

لديها أيضا واحدة، وهنا نفس النتائج, ، وهذا بالنسبة لي يوضح مكان المشكلة.

PgAdmin سوف تظهر لك تمثيل رسومي لشرح الخطة.يمكن أن يساعدك التبديل ذهابًا وإيابًا بين الاثنين في فهم معنى تمثيل النص.ومع ذلك، إذا كنت تريد فقط معرفة ما ستفعله، فقد تتمكن دائمًا من استخدام واجهة المستخدم الرسومية.

الوثائق الرسمية لـ PostgreSQL يقدم شرحًا مثيرًا للاهتمام وشاملاً حول كيفية فهم مخرجات الشرح.

إذا قمت بتثبيت pgadmin، يوجد زر شرح والذي بالإضافة إلى إعطاء مخرجات النص رسمًا تخطيطيًا لما يحدث، وإظهار عوامل التصفية والفرز ودمج المجموعات الفرعية التي أجدها مفيدة حقًا لمعرفة ما يحدث.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top