Saya mencoba membuat indeks parsial untuk tabel statis besar (1.2TB) di Postgres 9.4.
Data saya benar-benar statis, jadi saya bisa memasukkan semua data, lalu membuat semua indeks.
Dalam tabel 1.2TB ini, saya memiliki kolom bernama run_id
yang membagi data dengan bersih. Kami mendapatkan kinerja luar biasa dengan membuat indeks yang mencakup kisaran run_id
s. Ini sebuah contoh:
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
Indeks parsial ini memberi kami kecepatan permintaan yang diinginkan. Sayangnya, pembuatan setiap indeks parsial membutuhkan waktu sekitar 70 menit.
Sepertinya kami adalah CPU terbatas ( top
menunjukkan 100% untuk proses).
Adakah yang bisa saya lakukan untuk mempercepat pembuatan indeks parsial kami?
Spesifikasi sistem:
- 18 inti Xeon
- RAM 192 GB
- 12 SSD dalam RAID
- Autovacuum dimatikan
- maintenance_work_mem: 64GB (Terlalu tinggi?)
Spesifikasi tabel:
- Ukuran: 1,26 TB
- Jumlah baris: 10,537 Miliar
- Ukuran indeks umum: 3.2GB (ada varian ~ .5GB)
Definisi tabel:
CREATE TABLE run.perception(
id bigint NOT NULL,
run_id bigint NOT NULL,
frame bigint NOT NULL,
by character varying(45) NOT NULL,
by_anyone bigint NOT NULL,
by_me bigint NOT NULL,
by_s_id integer,
owning_p_id bigint NOT NULL,
obj_type_set bigint,
seq integer,
subj_id bigint NOT NULL,
subj_state_frame bigint NOT NULL,
CONSTRAINT perception_pkey PRIMARY KEY (id))
(Jangan terlalu banyak membaca nama kolom - Saya agak mengaburkannya.)
Info latar belakang:
- Kami memiliki tim tamu di tempat yang menggunakan data ini, tetapi sebenarnya hanya ada satu atau dua pengguna. (Data ini semua dihasilkan melalui simulasi.) Pengguna hanya mulai menganalisis data setelah sisipan selesai dan indeks dibuat sepenuhnya. Perhatian utama kami adalah mengurangi waktu yang diperlukan untuk menghasilkan data yang dapat digunakan, dan saat ini bottleneck adalah waktu pembuatan indeks.
- Kecepatan permintaan sudah sepenuhnya memadai saat menggunakan sebagian. Bahkan, saya pikir kita bisa meningkatkan jumlah proses yang dicakup oleh masing-masing indeks, dan masih mempertahankan kinerja kueri yang cukup baik.
- Dugaan saya adalah bahwa kita harus mempartisi tabel. Kami mencoba menguras semua opsi lain sebelum mengambil rute itu.
completely static
, lalu apa yang Anda maksud We have a separate team onsite that consumes this data
? Apakah Anda hanya mengindeks rentang run_id >= 266 AND run_id <= 270
atau seluruh tabel? Berapa harapan hidup setiap indeks / berapa banyak permintaan akan menggunakannya? Berapa banyak nilai yang berbeda untuk run_id
? Kedengarannya seperti ~ 15 Mio. baris per run_id
, yang akan membuatnya sekitar 800 nilai berbeda untuk run_id
? Mengapa obj_type_set
, by_s_id
, seq
tidak didefinisikan NOT NULL? Berapa persentase kasar nilai NULL untuk masing-masing?
run_id
? Didistribusikan secara merata? Ukuran indeks yang dihasilkan pada disk? Data statis, ok. Tetapi apakah Anda satu-satunya pengguna?