REINDEX tehlikeli midir?


17

COUNT(*)Birincil anahtarı olan 150.000 satır içeren bir tabloya çalışıyorum . Bu araç yaklaşık 5 dakika, bu yüzden bu bir indeksleme sorunu olduğunu anladım.

PostgreSQL kılavuzuna atıf :

REINDEX, dizinin içeriğinin sıfırdan yeniden oluşturulması nedeniyle dizinin düşmesine ve yeniden oluşturulmasına benzer. Bununla birlikte, kilitleme hususları oldukça farklıdır. REINDEX, dizinin üst tablosundaki yazma işlemlerini kilitler, ancak okumaları engellemez. Ayrıca, işlenmekte olan belirli bir dizin üzerinde özel bir kilit alır ve bu dizini kullanmaya çalışan okumaları engeller (...) Sonraki CREATE INDEX yazma işlemlerini kilitler, ancak okumaları kilitler; indeks orada olmadığından, hiçbir okuma onu kullanmaya çalışmaz, yani engelleme olmaz, ancak okumalar pahalı sıralı taramalara zorlanabilir.

Kendi deneyiminizden şunu söyleyebilir misiniz?

  • olan REINDEXINGtehlikeli? Veri tutarlılığına zarar verebilir mi?
  • Çok zaman alabilir mi?
  • Senaryom için olası bir çözüm mü?

Güncelleme:

Bizim için çalışan çözüm, aynı dizini farklı bir adla yeniden oluşturmak ve ardından eski dizini silmekti.

Dizin oluşturma çok hızlı ve dizin boyutunu 650 MB'dan 8 MB'a düşürdük. Bir kullanma COUNT(*)ile betweensadece 3 saniye sürer.

Yanıtlar:


15

Yeniden endeksleme tehlikeli değildir ve veri tutarlılığına zarar veremez. Ancak, zaman açısından kritik yazımlarınız varsa, tablo kilitliyse ve DML iptal edilirse verileri kaybedebilirsiniz.

Yeniden endeksleme çok zaman almamalıdır, ancak genellikle tüm tabloyu okumayı, dizin alanlarını sıralamayı ve yeni bir dizin yazmayı içerir. Verilen süre göz önüne alındığında, COUNT(*)muhtemelen beş dakika veya daha fazla sürecektir.

Bu bir indeksleme problemi değildir. COUNT(*)bir tablo taraması kullanmalıdır, bu durumda hiçbir dizin okunmaz. Bir çeşit ES probleminiz olmasını beklerdim.

Dizin kullanmayı COUNT(1)veya COUNT(pk_field)hangisini kullanabileceğini deneyin .

Unix veya Linux platformunda çalışıyorsanız, disk etkinliğini izlemek isteyebilirsiniz sar. Ayrıca, GÇ oranlarını önemli ölçüde azaltabilen arızalı bir diskiniz de olabilir.

Büyük nesneli tablolar da COUNT (*) için kayıt oluşturmak üzere ES'yi önemli ölçüde artırabilir.


2
Wiki.postgresql.org göre COUNT(*), en iyi seçimdir:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.
orange80

1

Sizin için en iyi cevaptan emin değilim. Ancak bu konu bazı iyi önerilerde bulunuyor gibi görünüyor: n http://postgresql.1045698.n5.nabble.com/count-performance-issue-td2067873.html

Bir not, satır sayılarını ayrı bir tabloda tutmak için bir TRIGGER uygulayabileceğinizdir (COUNT (*) uygulamalarınız tarafından sık sık çağrılırsa).

Yanıtlardan birkaçı, bunun yeterince yakın zamanda vakumlanmamış bir veritabanının belirtisi olduğunu gösteriyor (sunucunuzda veya özellikle bu veritabanında otomatik vakumun devre dışı olduğunu düşündürüyor)?

Başka bir öneri şuna benziyor:

ANALYZE tablename;
SELECT reltuple FROM pg_class WHERE relname = 'tablename';

Ve A. Kretschmer olarak tanımlanan biri şunları not eder:

Hayır. Geçerli dizin uygulaması, geçerli işlemdeki satır görünürlüğü hakkında bilgi içermez. Geçerli satırın geçerli işlem içinde görünür olup olmadığını öğrenmek için tüm veri tablosunu taramanız gerekir.

... bir performans kaygısı olan satır düzeyinde izinler hakkındaki yorumumu destekliyor.

Ayrıca WikiVS: MySQL ve PostgreSQL: COUNT (*) aramaları da yapıldı .

Google: postgresql count (*) performansını kullanarak bulduğum diğer sonuçları inceleyebilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.