لماذا ينخفض ​​أداء استعلام PostgreSQL بمرور الوقت ، ولكن تم استعادته عند إعادة البناء الفهرس

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

سؤال

حسب هذا صفحة في الدليل ، indexes don't need to be maintained. ومع ذلك ، فإننا نركض مع جدول postgresql الذي يحتوي على معدل مستمر updates, deletes و inserts أنه بمرور الوقت (بضعة أيام) يرى تدهورًا كبيرًا في استعلام. إذا حذفنا الفهرس وإعادة إنشاءه ، فسيتم استعادة أداء الاستعلام.

نحن نستخدم خارج إعدادات المربع.
بدأ الجدول في اختبارنا حاليًا فارغًا وينمو إلى نصف مليون صف. لديها صف كبير إلى حد ما (الكثير من حقول النص).

نحن searching based of an index, not the primary key (لقد أكدت أن الفهرس يستخدم ، على الأقل في ظل الظروف العادية)

يتم استخدام الجدول كمتجر ثابت لعملية واحدة. باستخدام postgreSQL على Windows مع عميل Java.

أنا على استعداد للتخلي insert and update performance لمواكبة أداء الاستعلام.

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

لقد درسنا forcing vacuuming و rebuild to run at certain times, ، لكني أظن locking period for such an action would cause our query to block. قد يكون هذا خيارًا ، ولكن هناك بعض الآثار المترتبة في الوقت الفعلي (من 3 إلى 5 ثوان) التي تتطلب تغييرات أخرى في الكود لدينا.

معلومة اضافية:الجدول والفهرس

CREATE TABLE icl_contacts
(
  id bigint NOT NULL,
  campaignfqname character varying(255) NOT NULL,
  currentstate character(16) NOT NULL,
  xmlscheduledtime character(23) NOT NULL,
...
25 or so other fields.  Most of them fixed or varying character fiel  
...
  CONSTRAINT icl_contacts_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE icl_contacts OWNER TO postgres;

CREATE INDEX icl_contacts_idx
  ON icl_contacts
  USING btree
  (xmlscheduledtime, currentstate, campaignfqname);

تحليل:

Limit  (cost=0.00..3792.10 rows=750 width=32) (actual time=48.922..59.601 rows=750 loops=1)
  ->  Index Scan using icl_contacts_idx on icl_contacts  (cost=0.00..934580.47 rows=184841 width=32) (actual time=48.909..55.961 rows=750 loops=1)
        Index Cond: ((xmlscheduledtime < '2010-05-20T13:00:00.000'::bpchar) AND (currentstate = 'SCHEDULED'::bpchar) AND ((campaignfqname)::text = '.main.ee45692a-6113-43cb-9257-7b6bf65f0c3e'::text))

ونعم ، أنا أدرك أن هناك مجموعة متنوعة من الأشياء we could do to normalize and improve the design of this table. قد تكون بعض هذه الخيارات متاحة لنا.

تركيزي في هذا السؤال هو حول الفهم how PostgresQL is managing the index and query over time (understand why, not just fix). إذا كان من الممكن أن يتم ذلك أو تم إعادة تمثيله بشكل كبير ، فسيكون هناك الكثير من التغييرات.

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

المحلول

يجب أن يقوم الفراغ التلقائي بالقيام بالخدعة ، شريطة تكوينه لأدائك المطلوب.

ملاحظات: الفراغ الكامل: سيؤدي ذلك إلى إعادة بناء إحصائيات الجدول واستعادة الكثير من مساحة القرص. إنه يغلق الجدول بأكمله.

الفراغ: سيؤدي ذلك إلى إعادة بناء إحصائيات الجدول واستعادة بعض مساحة القرص. يمكن تشغيله بالتوازي مع نظام الإنتاج ، ولكنه يولد الكثير من IO الذي يمكن أن يؤثر على الأداء.

تحليل: هذا سوف إعادة بناء إحصائيات مخطط الاستعلام. يتم تشغيل هذا بالفراغ ، ولكن يمكن تشغيله من تلقاء نفسه.

أكثر ملاحظات مفصلة موجودة هنا

نصائح أخرى

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

هذه رائحة مثل الفهرس الانتفاخ بالنسبة لي. أنا أحيلك إلى هذه الصفحة

http://www.postgresql.org/docs/8.3/static/routine-reindex.html

الذي يقول في الأسفل:

أيضًا ، بالنسبة لمؤشرات B-Tree ، يكون الفهرس الذي تم بناؤه حديثًا أسرع إلى حد ما للوصول من تلك التي تم تحديثها عدة مرات ، لأن الصفحات المجاورة منطقياً عادة ما تكون مجاورة جسديًا في مؤشر تم بناؤه حديثًا. (لا ينطبق هذا الاعتبار حاليًا على فهارس غير B-Tree.) قد يكون من المفيد أن يكرم بشكل دوري فقط لتحسين سرعة الوصول.

الذي يبدو أنه يتعارض مع الصفحة التي أشرت إليها قائلة إن الفهارس "لا تتطلب الصيانة أو ضبط".

هل حاولت "إنشاء فهرس متزامن"؟

هل قيمة '2010-05-20T13: 00: 00.000' التي تتم مقارنة xmlscheduledtime ، جزء من SQL ، أو يتم توفيرها كمعلمة؟

عند التخطيط لكيفية تشغيل الاستعلام ، فإن القول بأن الحقل يجب أن يكون أقل من معلمة مزودة ذات قيمة غير معروفة حتى الآن لا تمنح PostgreSQL الكثير. لا يعرف ما إذا كان ذلك سيتطابق تقريبًا مع جميع الصفوف ، أو بالكاد أي من الصفوف.

القراءة عن كيف يستخدم المخطط الإحصائيات يساعد بشكل كبير عند محاولة معرفة سبب استخدام قاعدة البيانات الخاصة بك.

قد تحصل على أداء أفضل من خلال تغيير ترتيب الحقول في هذا الفهرس المعقد ، أو إنشاء فهرس جديد ، مع طلب الحقول (CampamentFqName ، CurrentState ، XmlScheduledTim أن تكون مهتمًا به ، وسيكون كل من المسح الضوئي على مدى XMLSCheduledTime جميعًا صفوفًا تتبعها.

هذه حالة كتاب مدرسي. يجب عليك إعداد Autovacuum لتكون أكثر عدوانية.

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