Metode termudah untuk memecahkan masalah adalah untuk query waktu rinci dari PostgreSQL: EXPLAIN
. Untuk ini, Anda perlu menemukan setidaknya satu permintaan yang lengkap tetapi membutuhkan waktu lebih lama dari yang diharapkan. Katakanlah garis ini akan terlihat seperti
delete from mydata where id='897b4dde-6a0d-4159-91e6-88e84519e6b6';
Alih-alih benar-benar menjalankan perintah itu bisa Anda lakukan
begin;
explain (analyze,buffers,timing) delete from mydata where id='897b4dde-6a0d-4159-91e6-88e84519e6b6';
rollback;
Kembalikan pada akhirnya memungkinkan menjalankan ini tanpa benar-benar memodifikasi database tetapi Anda masih mendapatkan waktu yang terperinci dari berapa banyak. Setelah menjalankan itu, Anda mungkin menemukan dalam output bahwa beberapa pemicu menyebabkan penundaan besar:
...
Trigger for constraint XYZ123: time=12311.292 calls=1
...
Ini time
dalam ms (milidetik) sehingga memeriksa kendala ini memakan waktu sekitar 12,3 detik. Anda perlu menambahkan yang baru di INDEX
atas kolom yang diperlukan sehingga pemicu ini dapat dihitung secara efektif. Untuk referensi kunci asing, kolom yang merujuk ke tabel lain harus diindeks (yaitu, kolom sumber, bukan kolom target). PostgreSQL tidak secara otomatis membuat indeks untuk Anda dan DELETE
merupakan satu-satunya permintaan umum di mana Anda benar-benar membutuhkan indeks itu. Akibatnya, Anda mungkin telah mengakumulasikan data selama bertahun-tahun hingga Anda menemukan kasus DELETE
yang terlalu lambat karena tidak ada indeks.
Setelah Anda memperbaiki kinerja kendala itu (atau hal lain yang memakan waktu terlalu lama), ulangi perintah di begin
/ rollback
block sehingga Anda dapat membandingkan waktu eksekusi yang baru dengan yang sebelumnya. Lanjutkan sampai Anda puas dengan waktu respons penghapusan satu baris (saya mendapatkan satu kueri mulai dari 25,6 detik hingga 15 ms hanya dengan menambahkan indeks yang berbeda). Kemudian Anda dapat melanjutkan untuk menyelesaikan penghapusan penuh Anda tanpa ada peretasan.
(Catatan yang EXPLAIN
membutuhkan kueri yang dapat diselesaikan dengan sukses. Saya pernah punya masalah di mana PostgreSQL butuh waktu terlalu lama untuk mencari tahu bahwa satu penghapusan akan melanggar batasan kunci asing dan dalam kasus itu EXPLAIN
tidak dapat digunakan karena tidak akan memancarkan waktu untuk gagal pertanyaan. Saya tidak tahu cara mudah untuk men-debug masalah kinerja dalam kasus seperti itu.)