UPDATE طويلة في كيو
-
05-07-2019 - |
سؤال
ولقد تم تشغيل UPDATE على جدول يحتوي على 250 مليون الصفوف مع 3 مؤشر '؛ يستخدم هذا UPDATE جدول آخر يحتوي على 30 مليون الصفوف. تم تشغيله لمدة 36 ساعة الآن. وأنا أتساءل إذا ما هو وسيلة لمعرفة مدى قرب له أن يجري القيام به لأنه إذا أنها تخطط لاتخاذ مليون يوم لبذل كل شيء، وسوف يقتله. بعد ما اذا كان يحتاج فقط يوم آخر أو اثنين، وسوف تتيح تشغيله. هنا هو الاستعلام الأوامر:
UPDATE pagelinks SET pl_to = page_id
FROM page
WHERE
(pl_namespace, pl_title) = (page_namespace, page_title)
AND
page_is_redirect = 0
;
وهذا شرح ليست القضية هنا، وأود فقط أن أذكر وجود فهارس متعددة على طاولة كبيرة من أجل تبرير حد ما الفترة الزمنية التي يستغرقها لتحديثه. ولكن هنا هو شرح على أي حال:
Merge Join (cost=127710692.21..135714045.43 rows=452882848 width=57)
Merge Cond: (("outer".page_namespace = "inner".pl_namespace) AND ("outer"."?column4?" = "inner"."?column5?"))
-> Sort (cost=3193335.39..3219544.38 rows=10483593 width=41)
Sort Key: page.page_namespace, (page.page_title)::text
-> Seq Scan on page (cost=0.00..439678.01 rows=10483593 width=41)
Filter: (page_is_redirect = 0::numeric)
-> Sort (cost=124517356.82..125285665.74 rows=307323566 width=46)
Sort Key: pagelinks.pl_namespace, (pagelinks.pl_title)::text"
-> Seq Scan on pagelinks (cost=0.00..6169460.66 rows=307323566 width=46)
والآن كما بعثت مواز الاستعلام الأوامر من أجل قطرة واحدة من pagelinks 'م> الفهارس. وبطبيعة الحال فإنه ينتظر UPDATE الى النهاية (ولكن شعرت أنها تحاول على أي حال!). وبالتالي، لا أستطيع تحديد أي شيء من pagelinks م> خوفا من إفساد البيانات (إلا إذا كنت أعتقد أنه لن يكون في مأمن لقتل عملية مدير مكتب البريد DROP INDEX؟).
وحتى وأنا أتساءل عما اذا كان لهم هو الجدول الذي من شأنه أن تتبع من المبلغ من المجموعات الميتة أو شيء من هذا لانه سيكون من الجميل أن نعرف مدى سرعة أو إلى أي مدى تم التحديث في إنجاز مهمتها.
وتشك (كيو ليس ذكي كما اعتقدت، بل يحتاج الاستدلال)
المحلول
هل قرأت الوثائق كيو ل " عن طريق شرح أ > "، لتفسير المخرجات كنت تظهر؟
وأنا لست مستخدم كيو العادية، ولكن لقد قرأت للتو أن وثيقة، ومن ثم مقارنة مع الناتج EXPLAIN
كنت تظهر. يبدو الاستعلام UPDATE
ليتم استخدام لم فهارس، وانها اضطرت للقيام بمسح الجدول لفرز على حد سواء page
وpagelinks
. هذا النوع مما لا شك فيه كبيرة بما يكفي لحاجة ملفات القرص المؤقتة، وهو ما أعتقد تم إنشاؤها تحت temp_tablespace
الخاص بك.
وبعد ذلك أرى صفحات قاعدة البيانات يقدر قراءة. المستوى الأعلى من ان انتاج EXPLAIN
يقول (cost=127710692.21..135714045.43)
. وحدات هنا في القرص I / O يصل. لذلك يحدث الوصول إلى القرص أكثر من 135 مليون مرة للقيام بذلك UPDATE
.
لاحظ أنه حتى الأقراص 10،000rpm مع 5MS تسعى الوقت يمكن أن يحقق في أحسن الأحوال 200 I / O العمليات في الثانية الواحدة في ظل أفضل الظروف. وهذا يعني أن UPDATE
الخاص بك سوف تتخذ 188 ساعة (7.8 يوما) من القرص I / O، حتى لو تستطيع الحفاظ القرص المشبعة I / O لتلك الفترة (أي مستمر يقرأ / يكتب مع عدم وجود فواصل). هذا أمر مستحيل، وأتوقع الإنتاجية الفعلية ليكون خارج بأمر ما لا يقل عن حجمها، خصوصا منذ كان لديك شك في استخدام هذا الخادم لجميع أنواع أعمال أخرى في نفس الوقت. لذلك كنت أعتقد أنك فقط جزء من الطريق من خلال UPDATE
الخاص بك.
إذا كان لي، كنت قد قتلوا هذا الاستعلام في اليوم الأول، وجدت وسيلة أخرى من أداء UPDATE
التي جعلت استخدام أفضل للمؤشرات ولا تتطلب الفرز على القرص. وربما كنت لا تستطيع أن تفعل ذلك في بيان SQL واحد.
وأما بالنسبة DROP INDEX
الخاص بك، وأود أن أعتقد انها ببساطة حجب، في انتظار وصول خاص إلى طاولة المفاوضات، وعلى الرغم من أنها في هذه الحالة اعتقد انه يمكن ربما قتله.
نصائح أخرى
وهذه هي قديمة جدا، ولكن إذا كنت ترغب في طريقة لmonitore التحديث ... تذكر أن تسلسل تتأثر على الصعيد العالمي، لذلك أنت فقط يمكن أن تخلق واحد لmonitore هذا التحديث في دورة أخرى من خلال ذلك:
create sequence yourprogress;
UPDATE pagelinks SET pl_to = page_id
FROM page
WHERE
(pl_namespace, pl_title) = (page_namespace, page_title)
AND
page_is_redirect = 0 AND NEXTVAL('yourprogress')!=0;
وبعد ذلك في جلسة أخرى مجرد القيام بذلك (لا تقلق بشأن المعاملات، كما تتأثر تسلسل عالميا):
select last_value from yourprogress;
وهذا وسوف تظهر كم عدد خطوط والتأثر، حتى تتمكن من تقدير المدة التي سوف تتخذ.
وفي نهاية عادلة إعادة تشغيل التسلسل الخاص بك للقيام محاولة أخرى:
alter sequence yourprogress restart with 1;
وأو مجرد قطرة:
drop sequence yourprogress;
وتحتاج الفهارس أو، كما أشار بيل خارج، وسوف تحتاج إلى القيام بمسح متتابعة على كافة الجداول.
CREATE INDEX page_ns_title_idx on page(page_namespace, page_title);
CREATE INDEX pl_ns_title_idx on pagelink(pl_namespace, pl_title);
CREATE INDEX page_redir_idx on page(page_is_redirect);