Bagan, laporan, dan analitik - semua ini ada di back-office setiap perusahaan, bahkan sangat kecil. Ketika menjadi padat di tabel biasa di Excel / Numbers / Libre, tetapi data masih tidak terlalu besar, solusi tradisional untuk kebutuhan internal perusahaan sering dibangun menggunakan database relasional seperti PostgreSQL, MySQL atau MariaDB.
Database ini gratis, berkat SQL mereka dapat dengan mudah diintegrasikan dengan komponen lain dalam sistem, mereka populer dan sebagian besar pengembang dan analis dapat bekerja dengannya. Mereka dapat mencerna muatan (lalu lintas dan volume) dengan cukup banyak hingga dapat bertahan dengan tenang sampai perusahaan mampu memberikan solusi yang lebih kompleks (dan mahal) untuk analisis dan laporan.
Posisi awal
Namun, bahkan dalam teknologi yang telah berulang kali dipelajari, selalu ada nuansa berbeda yang tiba-tiba dapat menambah kekhawatiran para insinyur. Selain keandalan, masalah yang paling sering disebutkan dengan database adalah kinerjanya. Jelas, dengan peningkatan jumlah data, tingkat respons DB menurun, tetapi jika hal ini dapat diprediksi dan konsisten dengan peningkatan beban, maka ini tidak terlalu buruk. Anda selalu dapat melihat di muka ketika basis data mulai menuntut perhatian dan merencanakan peningkatan atau transisi ke basis data yang berbeda secara mendasar. Jauh lebih buruk jika kinerja basis data menurun tanpa terduga.
Topik meningkatkan kinerja basis data sama tuanya dengan dunia dan sangat luas, dan dalam artikel ini saya ingin fokus hanya pada satu arah. Yaitu, pada mengevaluasi efektivitas rencana kueri dalam database PostgreSQL, serta mengubah efisiensi ini dari waktu ke waktu untuk membuat perilaku penjadwal basis data lebih dapat diprediksi.
Terlepas dari kenyataan bahwa banyak hal yang akan dibahas berlaku untuk semua versi terbaru dari database ini, contoh di bawah ini berarti versi 11.2, yang terakhir saat ini.
Sebelum kita menyelami rinciannya, masuk akal untuk menyimpang dan mengatakan beberapa kata tentang dari mana masalah kinerja dalam basis data relasional dapat berasal. Apa sebenarnya yang sibuk dengan database ketika "melambat"? Kurangnya memori (sejumlah besar disk atau akses jaringan), prosesor yang lemah, ini semua adalah masalah yang jelas dengan solusi yang jelas, tetapi apa lagi yang dapat mempengaruhi kecepatan eksekusi permintaan?
Menyegarkan kenangan
Agar database merespons permintaan SQL, ia perlu membangun rencana kueri (di mana tabel dan kolom untuk melihat indeks apa yang diperlukan, apa yang dipilih dari sana, apa yang akan dibandingkan dengan, berapa banyak memori yang diperlukan, dan sebagainya). Rencana ini dibentuk dalam bentuk pohon, simpulnya hanya beberapa operasi tipikal, dengan kompleksitas komputasi yang berbeda. Berikut adalah beberapa di antaranya, misalnya (N adalah jumlah baris yang digunakan untuk melakukan operasi):
Operasi | Apa yang dilakukan | Biaya |
---|
PILIH ... DI MANA ... data mengambil operasi |
Pemindaian seq | Kami memuat setiap baris dari tabel dan memeriksa kondisinya. | O (N) |
Pemindaian indeks (indeks b-tree) | Data langsung berada di indeks, jadi kami mencari berdasarkan kondisi untuk elemen-elemen indeks yang diperlukan dan mengambil data dari sana. | O (log (N)), mencari elemen di pohon yang disortir. |
Pemindaian indeks (indeks hash) | Data langsung berada di indeks, jadi kami mencari berdasarkan kondisi untuk elemen-elemen indeks yang diperlukan dan mengambil data dari sana. | O (1), mencari item dalam tabel hash, tidak termasuk biaya pembuatan hash |
Bitmap heap scan | Kami memilih jumlah garis yang diperlukan menurut indeks, kemudian kami hanya memuat garis yang diperlukan dan melakukan pemeriksaan tambahan dengannya. | Pemindaian Indeks + Pemindaian Seq (M), Di mana M adalah jumlah baris yang ditemukan setelah Pemindaian Indeks. Diasumsikan bahwa M << N, mis. indeks lebih berguna daripada Pemindaian Seq. |
Bergabung dengan operasi (BERGABUNG, PILIH dari beberapa tabel) |
Loop bersarang | Untuk setiap baris dari tabel kiri, cari baris yang sesuai di tabel kanan. | O (N 2 ). Tetapi jika salah satu tabel jauh lebih kecil dari yang lain (kamus) dan praktis tidak tumbuh seiring waktu, maka biaya aktual dapat turun menjadi O (N). |
Hash bergabung | Untuk setiap baris dari tabel kiri dan kanan, kami mempertimbangkan hash, yang mengurangi jumlah pencarian opsi koneksi yang mungkin. | O (N), tetapi dalam kasus fungsi hash yang sangat tidak efisien atau sejumlah besar bidang yang identik untuk koneksi, mungkin ada O (N 2 ) |
Gabung bergabung | Berdasarkan kondisi, kami mengurutkan tabel kiri dan kanan, setelah itu kami menggabungkan dua daftar yang diurutkan | O (N * log (N)) Menyortir biaya + menelusuri daftar. |
Operasi Agregasi (GROUP BY, DISTINCT) |
Kelompok agregat | Kami mengurutkan tabel sesuai dengan kondisi agregasi dan kemudian dalam daftar diurutkan kami mengelompokkan baris yang berdekatan. | O (N * log (N)) |
Agregat hash | Kami mempertimbangkan hash untuk kondisi agregasi untuk setiap baris. Untuk baris dengan hash yang sama, kami melakukan agregasi. | O (N) |
Seperti yang Anda lihat, biaya permintaan sangat tergantung pada bagaimana data berada di tabel dan bagaimana urutan ini sesuai dengan operasi hash yang digunakan. Nested Loop, meskipun biayanya di O (N
2 ), bisa lebih menguntungkan daripada Hash Join atau Gabung Bergabung ketika salah satu tabel yang bergabung merosot menjadi satu atau beberapa baris.
Selain sumber daya CPU, biaya juga termasuk penggunaan memori. Keduanya sumber daya terbatas, sehingga perencana kueri harus menemukan kompromi. Jika dua tabel secara matematis lebih menguntungkan untuk terhubung melalui Hash Join, tetapi tidak ada ruang untuk tabel hash yang begitu besar dalam memori, database mungkin terpaksa menggunakan Gabung Gabung, misalnya. Nested Loop "lambat" umumnya tidak memerlukan memori tambahan dan siap untuk menghasilkan hasil setelah peluncuran.
Biaya relatif dari operasi ini lebih jelas ditunjukkan pada grafik. Ini bukan angka absolut, hanya perkiraan rasio operasi yang berbeda.

Bagan Nested Loop "dimulai" di bawah, karena tidak memerlukan perhitungan tambahan atau alokasi memori atau menyalin data antara, tetapi memiliki biaya O (N
2 ). Gabung Gabung dan Hash Gabung memiliki biaya awal yang lebih tinggi, namun, setelah beberapa nilai N, mereka mulai mengalahkan Nested Loop pada waktunya. Penjadwal mencoba untuk memilih paket dengan biaya terendah dan pada grafik di atas mengikuti operasi yang berbeda dengan N yang berbeda (panah putus-putus hijau). Dengan jumlah garis hingga N1, lebih menguntungkan untuk menggunakan Nested Loop, dari N1 ke N2 lebih menguntungkan untuk Bergabung Gabung, kemudian setelah N2 menjadi lebih menguntungkan untuk Hash Bergabung, namun Hash Join membutuhkan memori untuk membuat tabel hash. Dan ketika mencapai N3, memori ini menjadi tidak mencukupi, yang mengarah pada penggunaan paksa Gabung Gabung.
Saat memilih paket, penjadwal memperkirakan biaya setiap operasi dalam paket menggunakan seperangkat biaya relatif dari beberapa operasi "atom" dalam database. Sebagai contoh, perhitungan, perbandingan, memuat halaman ke memori, dll. Berikut adalah daftar dari beberapa parameter ini dari konfigurasi default, tidak banyak dari mereka:
Konstanta biaya relatif | Nilai standar |
---|
seq_page_cost | 1.0 |
random_page_cost | 4.0 |
cpu_tuple_cost | 0,01 |
cpu_index_tuple_cost | 0,005 |
cpu_operator_cost | 0,0025 |
parallel_tuple_cost | 0,1 |
parallel_setup_cost | 1000.0 |
Benar, konstanta ini saja sedikit, Anda masih perlu tahu sangat "N", yaitu, berapa banyak baris dari hasil sebelumnya harus diproses dalam setiap operasi tersebut. Batas atas jelas di sini - database "tahu" berapa banyak data dalam tabel apa pun dan selalu dapat menghitung "secara maksimal". Misalnya, jika Anda memiliki dua tabel masing-masing 100 baris, maka bergabung dengan mereka dapat menghasilkan dari 0 hingga 10.000 baris dalam output. Dengan demikian, operasi input selanjutnya dapat memiliki hingga 10.000 saluran.
Tetapi jika Anda tahu setidaknya sedikit tentang sifat data dalam tabel, jumlah baris ini dapat diprediksi lebih akurat. Misalnya, untuk dua tabel 100 baris dari contoh di atas, jika Anda tahu sebelumnya bahwa gabungan tidak akan menghasilkan 10 ribu baris, tetapi 100 yang sama, perkiraan biaya operasi berikutnya sangat berkurang. Dalam hal ini, rencana ini bisa lebih efektif daripada yang lain.
Optimasi di luar kotak
Agar penjadwal dapat lebih akurat memprediksi ukuran hasil antara, PostgreSQL menggunakan kumpulan statistik pada tabel, yang diakumulasikan dalam pg_statistic, atau dalam versi yang lebih mudah dibaca - di pg_stats. Itu diperbarui secara otomatis ketika vakum dimulai, atau secara eksplisit dengan perintah ANALYZE. Tabel ini menyimpan berbagai informasi tentang data apa dan sifat apa yang ada di dalam tabel. Secara khusus, histogram nilai, persentase bidang kosong, dan informasi lainnya. Perencana menggunakan semua ini untuk lebih akurat memprediksi jumlah data untuk setiap operasi di pohon rencana, dan dengan demikian lebih akurat menghitung biaya operasi dan rencana secara keseluruhan.
Ambil contoh kueri:
SELECT t1.important_value FROM t1 WHERE t1.a > 100
Asumsikan bahwa histogram dari nilai di kolom "t1.a" mengungkapkan bahwa nilai lebih dari 100 ditemukan di sekitar 1% dari baris tabel. Kemudian kita dapat memperkirakan bahwa sampel seperti itu akan mengembalikan sekitar seperseratus dari semua baris dari tabel "t1".
Basis data memberi Anda kesempatan untuk melihat perkiraan biaya rencana melalui perintah EXPLAIN, dan waktu aktual operasinya - menggunakan EXPLAIN ANALYZE.
Tampaknya dengan statistik otomatis semuanya harus baik-baik saja sekarang, tetapi mungkin ada kesulitan. Ada
artikel bagus tentang ini
dari Data Citus , dengan contoh ketidakefisienan statistik otomatis dan pengumpulan statistik tambahan menggunakan CREATE STATISTICS (tersedia dengan PG 10.0).
Jadi, untuk penjadwal, ada dua sumber kesalahan dalam menghitung biaya:
- Biaya relatif operasi primitif (seq_page_cost, cpu_operator_cost, dan sebagainya) secara default dapat sangat berbeda dari kenyataan (biaya cpu 0,01, biaya pemuatan halaman srq - 1 atau 4 untuk pemuatan halaman acak). Jauh dari kenyataan bahwa 100 perbandingan akan sama dengan 1 halaman memuat.
- Galat memprediksi jumlah baris dalam operasi perantara. Biaya operasi sebenarnya dalam kasus ini bisa sangat berbeda dari perkiraan.
Dalam pertanyaan yang kompleks, menyusun dan memperkirakan semua rencana yang mungkin bisa memakan banyak waktu dengan sendirinya. Apa gunanya mengembalikan data dalam 1 detik jika database hanya merencanakan satu menit permintaan? PostgreSQL memiliki pengoptimal Geqo untuk situasi ini, itu adalah penjadwal yang tidak membangun semua opsi yang mungkin untuk rencana, tetapi mulai dengan beberapa yang acak dan menyelesaikan yang terbaik, memprediksi cara untuk mengurangi biaya. Semua ini juga tidak meningkatkan keakuratan ramalan, meskipun mempercepat pencarian untuk setidaknya beberapa rencana yang kurang lebih optimal.
Rencana mendadak - pesaing
Jika semuanya berjalan dengan baik, permintaan Anda dipenuhi secepat mungkin. Saat jumlah data meningkat, kecepatan eksekusi kueri dalam basis data secara bertahap meningkat, dan setelah beberapa waktu, mengamatinya, Anda dapat memperkirakan kapan dibutuhkan untuk meningkatkan memori atau jumlah inti CPU atau memperluas cluster, dll.
Tetapi kita harus memperhitungkan fakta bahwa rencana optimal memiliki pesaing dengan biaya eksekusi yang dekat, yang tidak kita lihat. Dan jika database tiba-tiba mengubah rencana kueri ke yang lain, ini mengejutkan. Ada baiknya jika database melompat ke rencana yang lebih efisien. Dan jika tidak? Mari kita lihat gambarnya, misalnya. Ini adalah perkiraan biaya dan waktu nyata dari implementasi dua paket (merah dan hijau):

Di sini, satu rencana ditunjukkan dengan warna hijau dan “pesaing” terdekatnya berwarna merah. Garis putus-putus menunjukkan grafik proyeksi biaya, garis padat adalah waktu nyata. Panah putus-putus berwarna abu-abu menunjukkan pilihan perencana.
Misalkan suatu Jumat malam yang baik jumlah baris yang diprediksi dalam beberapa operasi antara mencapai N1 dan perkiraan "merah" mulai mengungguli yang "hijau". Penjadwal mulai menggunakannya. Waktu eksekusi permintaan aktual segera melompat (beralih dari garis solid hijau ke merah), yaitu, jadwal degradasi database mengambil bentuk langkah (atau mungkin "dinding"). Dalam praktiknya, "dinding" seperti itu dapat meningkatkan waktu eksekusi kueri dengan urutan besarnya atau lebih.
Perlu dicatat bahwa situasi ini mungkin lebih khas untuk back office dan analitik daripada untuk front-end, karena yang terakhir biasanya disesuaikan dengan permintaan yang lebih simultan dan, oleh karena itu, menggunakan kueri yang lebih sederhana dalam database, di mana kesalahan dalam perkiraan prakiraan rencana kurang. Jika ini adalah basis data untuk pelaporan atau analitik, pertanyaan dapat menjadi rumit.
Bagaimana cara hidup dengannya?
Timbul pertanyaan: apakah mungkin untuk meramalkan rencana tak terlihat "bawah air" seperti itu? Bagaimanapun, masalahnya bukan bahwa mereka tidak optimal, tetapi bahwa beralih ke rencana lain dapat terjadi tanpa terduga, dan, menurut hukum kekejaman, pada saat yang paling disayangkan untuk ini.
Sayangnya, Anda tidak dapat melihatnya secara langsung, tetapi Anda dapat mencari rencana alternatif dengan mengubah bobot aktual yang dipilih. Arti dari pendekatan ini adalah untuk menghilangkan dari pandangan rencana saat ini, yang dianggap penjadwal optimal, sehingga salah satu pesaing terdekatnya menjadi optimal, dan dengan demikian, ia dapat dilihat melalui tim EXPLAIN. Secara berkala memeriksa perubahan biaya dalam "pesaing" dan dalam rencana utama, Anda dapat menilai kemungkinan bahwa basis data akan segera "melompat" ke rencana lain.
Selain mengumpulkan data tentang perkiraan rencana alternatif, Anda dapat menjalankannya dan mengukur kinerjanya, yang juga memberikan gambaran tentang "kesejahteraan" internal database.
Mari kita lihat alat apa yang kita miliki untuk eksperimen semacam itu.
Pertama, Anda dapat secara eksplisit "melarang" operasi tertentu menggunakan variabel sesi. Mudahnya, mereka tidak perlu diubah dalam konfigurasi dan database dimuat kembali, nilainya hanya berubah di sesi terbuka saat ini dan tidak memengaruhi sesi lain, sehingga Anda dapat bereksperimen langsung dengan data nyata. Berikut adalah daftar mereka dengan nilai default. Hampir semua operasi termasuk:
Operasi yang Digunakan | Nilai standar |
---|
enable_bitmapscan enable_hashagg enable_hashjoin enable_indexscan enable_indexonlyscan enable_material enable_mergejoin enable_nestloop aktifkan_parallel_append enable_seqscan enable_sort enable_tidscan enable_parallel_hash enable_partition_pruning | pada |
enable_partitionwise_join enable_partitionwise_aggregate | off |
Dengan melarang atau mengizinkan operasi tertentu, kami memaksa penjadwal untuk memilih paket lain yang bisa kita lihat dengan perintah EXPLAIN yang sama. Bahkan, "larangan" operasi tidak melarang penggunaannya, tetapi hanya sangat meningkatkan biaya mereka. Dalam PostgreSQL, setiap operasi "terlarang" secara otomatis menumpuk biaya yang setara dengan 10 miliar unit konvensional. Selain itu, dalam MENJELASKAN, bobot total rencana dapat berubah menjadi sangat tinggi, tetapi dengan latar belakang puluhan miliar ini, bobot operasi yang tersisa terlihat jelas, karena biasanya cocok dengan pesanan yang lebih kecil.
Yang menarik adalah dua dari operasi berikut:
- Hash Bergabung. Kompleksitasnya adalah O (N), tetapi dengan kesalahan dengan perkiraan jumlah hasil, Anda tidak dapat memuatnya dalam memori dan Anda harus melakukan Penggabungan Gabung, dengan biaya O (N * log (N)).
- Nested Loop. Kompleksitasnya adalah O (N 2 ), oleh karena itu, kesalahan dalam perkiraan ukuran secara kuadratik mempengaruhi kecepatan koneksi semacam itu.
Sebagai contoh, mari kita ambil beberapa bilangan real dari kueri, optimisasi yang kami lakukan di perusahaan kami.
Paket 1. Dengan semua operasi yang diizinkan, total biaya paket paling optimal adalah 274962,09 unit.
Paket 2. Dengan loop terlarang "terlarang", biaya meningkat menjadi 40000534153,85. Ini 40 miliar yang merupakan bagian terbesar dari biaya adalah 4 kali Nested Loop digunakan, meskipun ada larangan. Dan sisanya 534153,85 - ini tepatnya perkiraan biaya semua operasi lain dalam rencana. Seperti yang kita lihat, sekitar 2 kali lebih tinggi dari biaya rencana optimal, yaitu cukup dekat.
Paket 3. Dengan Hash Join yang “terlarang”, biayanya adalah 383253,77. Rencana itu benar-benar dibuat tanpa menggunakan operasi Hash Join, karena kami tidak melihat miliaran. Biayanya, bagaimanapun, adalah 30% lebih tinggi daripada yang optimal, yang juga sangat dekat.
Pada kenyataannya, waktu eksekusi permintaan adalah sebagai berikut:
Paket 1 (semua operasi diizinkan) selesai dalam ~ 9 menit.
Plan 2 (dengan loop terlarang "terlarang") selesai dalam 1,5 detik.
Plan 3 (dengan hash bergabung "dilarang") selesai dalam ~ 5 menit.
Alasannya, seperti yang Anda lihat, adalah prediksi yang salah dari biaya Nested Loop. Memang, ketika membandingkan EXPLAIN dengan EXPLAIN ANALYZE, kesalahan terdeteksi di dalamnya dengan definisi N yang naas dalam operasi menengah. Alih-alih satu baris yang diprediksi, Nested Loop menemukan beberapa ribu baris, yang menyebabkan waktu eksekusi kueri meningkat beberapa kali lipat.
Penghematan dengan Hash Join yang “terlarang” dikaitkan dengan penggantian hashing dengan sorting dan Gabung Bergabung, yang bekerja lebih cepat dalam hal ini daripada Hash Bergabung. Perhatikan bahwa rencana 2 ini pada kenyataannya hampir dua kali lebih cepat daripada rencana "optimal" 1. Meskipun diprediksi akan lebih lambat.
Dalam praktiknya, jika permintaan Anda tiba-tiba (setelah peningkatan DB atau dengan sendirinya) mulai berjalan lebih lama dari sebelumnya, pertama-tama cobalah untuk menolak Hash Bergabung atau Nested Loop dan lihat bagaimana ini memengaruhi kecepatan kueri. Jika berhasil, Anda setidaknya dapat mencekal paket baru yang tidak optimal, dan kembali ke yang cepat sebelumnya.
Untuk melakukan ini, Anda tidak perlu mengubah file konfigurasi PostgreSQL dengan restart database, cukup sederhana di konsol mana pun untuk mengubah nilai variabel yang diinginkan untuk sesi terbuka dari database. Sesi yang tersisa tidak akan terpengaruh, konfigurasi hanya akan berubah untuk sesi Anda saat ini. Misalnya, seperti ini:
SET enable_hashjoin='on'; SET enable_nestloop='off'; SELECT … FROM … ( )
Cara kedua untuk memengaruhi pilihan rencana adalah mengubah bobot operasi tingkat rendah. Tidak ada resep universal di sini, tetapi, misalnya, jika Anda memiliki database dengan cache "warmed" dan seluruh data disimpan dalam memori, kemungkinan biaya pemuatan halaman berurutan tidak berbeda dari biaya pemuatan halaman acak. Sedangkan dalam konfigurasi default, acak adalah 4 kali lebih mahal daripada berurutan.
Atau, contoh lain, biaya bersyarat untuk menjalankan pemrosesan paralel adalah 1000 secara default, sedangkan biaya memuat halaman adalah 1.0. Masuk akal untuk memulai dengan mengubah hanya satu parameter pada satu waktu untuk menentukan apakah itu mempengaruhi pilihan rencana. Cara termudah adalah mulai dengan mengatur parameter ke 0 atau beberapa nilai tinggi (1 juta).
Namun, perlu diingat bahwa dengan meningkatkan kinerja dalam satu permintaan Anda dapat menurunkannya di permintaan lainnya. Secara umum, ada bidang yang luas untuk eksperimen. Lebih baik untuk mencoba mengubahnya satu per satu, satu per satu.
Opsi Perawatan Alternatif
Sebuah cerita tentang penjadwal tidak akan lengkap tanpa menyebutkan setidaknya dua ekstensi PostgreSQL.
Yang pertama adalah
SR_PLAN , untuk menyimpan paket yang dihitung dan memaksa penggunaan selanjutnya. Ini membantu membuat perilaku basis data lebih dapat diprediksi dalam hal pilihan rencana.
Yang kedua adalah
Adaptive Query Optimizer , yang mengimplementasikan umpan balik ke penjadwal dari eksekusi real-time dari query, yaitu, scheduler mengukur hasil aktual dari query yang dieksekusi dan menyesuaikan rencananya di masa depan dengan mempertimbangkan hal ini. Basis data dengan demikian "menyetel sendiri" untuk data dan kueri tertentu.
Apa lagi yang dilakukan database ketika melambat?
Sekarang setelah kami menyortir perencanaan kueri, kami akan melihat apa lagi yang bisa ditingkatkan baik dalam database itu sendiri maupun dalam aplikasi yang menggunakannya untuk mendapatkan kinerja maksimum darinya.
Misalkan rencana kueri sudah optimal. Jika kita mengecualikan masalah yang paling jelas (memori rendah atau disk / jaringan lambat), maka masih ada biaya untuk menghitung hash. Mungkin ada peluang besar untuk perbaikan PostgreSQL di masa depan (menggunakan GPU atau bahkan instruksi SSE2 / SSE3 / AVX dari CPU), tetapi sejauh ini belum dilakukan dan perhitungan hash hampir tidak pernah menggunakan kemampuan perangkat keras dari perangkat keras. Anda dapat sedikit membantu dalam database ini.
Jika Anda perhatikan, secara default indeks di PostgreSQL dibuat sebagai b-tree. Kegunaan mereka adalah mereka cukup fleksibel. Indeks semacam itu dapat digunakan baik dengan kondisi kesetaraan dan dengan kondisi perbandingan (lebih atau kurang). Menemukan item dalam indeks semacam itu adalah biaya logaritmik. Tetapi jika kueri Anda hanya berisi kondisi kesetaraan, indeks juga dapat dibuat sebagai indeks hash, yang biayanya konstan.
Selanjutnya, Anda masih dapat mencoba memodifikasi permintaan untuk menggunakan eksekusi paralelnya. Untuk memahami persis bagaimana menulis ulang, yang terbaik adalah membiasakan diri dengan daftar kasus ketika paralelisme secara otomatis dilarang oleh penjadwal dan menghindari situasi seperti itu.
Manual tentang topik ini menjelaskan secara singkat semua situasi, jadi tidak masuk akal untuk mengulanginya di sini.
Apa yang harus dilakukan jika permintaan itu masih tidak bisa membuat paralel? Sangat menyedihkan melihat bagaimana dalam basis data multi-inti Anda yang kuat, di mana Anda adalah satu-satunya klien, satu inti 100% terisi, dan semua kernel lainnya hanya melihatnya. Dalam hal ini, Anda harus membantu database dari aplikasi. Karena setiap sesi memiliki intinya sendiri, Anda dapat membuka beberapa sesi dan membagi kueri umum menjadi beberapa bagian, membuat pilihan yang lebih pendek dan lebih cepat, menggabungkannya ke dalam hasil umum yang sudah ada dalam aplikasi. Ini akan menempati sumber daya CPU maksimum yang tersedia di database PostgreSQL.
Sebagai kesimpulan, saya ingin mencatat bahwa opsi diagnostik dan optimisasi di atas hanyalah puncak gunung es, namun mereka cukup mudah digunakan dan dapat membantu mengidentifikasi masalah secara langsung pada data operasional tanpa risiko merusak konfigurasi atau mengganggu pengoperasian aplikasi lain.
Pertanyaan yang berhasil, dengan rencana yang akurat dan singkat.