PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Optimasi Kueri di PostgreSQL. JELASKAN Dasar-dasar – Bagian 2

Dalam artikel saya sebelumnya, kami mulai menjelaskan dasar-dasar perintah EXPLAIN dan menganalisis apa yang terjadi di PostgreSQL saat menjalankan kueri.

Saya akan terus menulis tentang dasar-dasar EXPLAIN di PostgreSQL. Informasi tersebut merupakan review singkat dari Understanding EXPLAIN oleh Guillaume Lelarge. Saya sangat merekomendasikan membaca yang asli karena beberapa informasi terlewatkan.

Tembolok

Apa yang terjadi pada level fisik saat menjalankan kueri kita? Mari kita cari tahu. Saya menggunakan server saya di Ubuntu 13.10 dan menggunakan cache disk pada level OS.

Saya menghentikan PostgreSQL, melakukan perubahan pada sistem file, menghapus cache, dan menjalankan PostgreSQL:

> sudo service postgresql-9.3 stop
> sudo sync
> sudo su -
# echo 3 > /proc/sys/vm/drop_caches
# exit
> sudo service postgresql-9.3 start

Saat cache dibersihkan, jalankan kueri dengan opsi BUFFERS

EXPLAIN (ANALYZE,BUFFERS) SELECT * FROM foo;

Kami membaca tabel dengan blok. Cache kosong. Kami harus mengakses 8334 blok untuk membaca seluruh tabel dari disk.

Buffer:pembacaan bersama adalah jumlah blok yang dibaca PostgreSQL dari disk.

Jalankan kueri sebelumnya

EXPLAIN (ANALYZE,BUFFERS) SELECT * FROM foo;

Buffer:hit bersama adalah jumlah blok yang diambil dari cache PostgreSQL.

Dengan setiap kueri, PostgreSQL mengambil lebih banyak data dari cache, dengan demikian, mengisi cache-nya sendiri.

Operasi baca cache lebih cepat daripada operasi baca disk. Anda dapat melihat tren ini dengan melacak nilai Total runtime.

Ukuran penyimpanan cache ditentukan oleh konstanta shared_buffers dalam file postgresql.conf.

DIMANA

Tambahkan kondisi ke kueri

EXPLAIN SELECT * FROM foo WHERE c1 > 500;

Tidak ada indeks di atas meja. Saat menjalankan kueri, setiap catatan tabel dipindai secara berurutan (Pemindaian Seq) dan dibandingkan dengan kondisi c1> 500. Jika kondisi terpenuhi, catatan ditambahkan ke hasil. Jika tidak, itu dibuang. Filter menunjukkan perilaku ini, serta peningkatan nilai biaya.

Perkiraan jumlah baris berkurang.

Artikel asli menjelaskan mengapa biaya mengambil nilai ini, dan bagaimana perkiraan jumlah baris dihitung.

Saatnya membuat indeks.

CREATE INDEX ON foo(c1);
EXPLAIN SELECT * FROM foo WHERE c1 > 500;

Perkiraan jumlah baris telah berubah. Bagaimana dengan indeks?

EXPLAIN (ANALYZE) SELECT * FROM foo WHERE c1 > 500;

Hanya 510 baris lebih dari 1 juta yang difilter. PostgreSQL harus membaca lebih dari 99,9% tabel.

Kami akan memaksa untuk menggunakan indeks dengan menonaktifkan Seq Scan:

SET enable_seqscan TO off;
EXPLAIN (ANALYZE) SELECT * FROM foo WHERE c1 > 500;

Dalam Pemindaian Indeks dan Indeks Cond, indeks foo_c1_idx digunakan sebagai ganti Filter.

Saat memilih seluruh tabel, menggunakan indeks akan meningkatkan biaya dan waktu untuk mengeksekusi kueri.

Aktifkan Pemindaian Seq:

SET enable_seqscan TO on;

Ubah kueri:

EXPLAIN SELECT * FROM foo WHERE c1 < 500;

Di sini perencana menggunakan indeks.

Sekarang, mari kita rumitkan nilainya dengan menambahkan bidang teks.

EXPLAIN SELECT * FROM foo
        WHERE c1 < 500 AND c2 LIKE 'abcd%';

Seperti yang Anda lihat, indeks foo_c1_idx digunakan untuk c1 <500. Untuk melakukan c2 ~~ ‘abcd%’::text, gunakan filter.

Perlu dicatat bahwa format POSIX dari operator LIKE digunakan dalam output hasil. Jika hanya ada kolom teks dalam kondisi:

EXPLAIN (ANALYZE)
SELECT * FROM foo WHERE c2 LIKE 'abcd%';

Pemindaian Seq diterapkan.

Buat indeks dengan c2:

CREATE INDEX ON foo(c2);
EXPLAIN (ANALYZE) SELECT * FROM foo
WHERE c2 LIKE 'abcd%';

Indeks tidak diterapkan karena database saya untuk bidang pengujian menggunakan pengkodean UTF-8.

Saat membangun indeks, perlu untuk menentukan kelas operator text_pattern_ops:

CREATE INDEX ON foo(c2 text_pattern_ops);
EXPLAIN SELECT * FROM foo WHERE c2 LIKE 'abcd%';

Besar! Berhasil!

Pemindaian Indeks Bitmap menggunakan indeks foo_c2_idx1 untuk menentukan catatan yang kita butuhkan. Kemudian, PostgreSQL pergi ke tabel (Bitmap Heap Scan) untuk memastikan bahwa catatan ini benar-benar ada. Perilaku ini mengacu pada versi PostgreSQL.

Jika Anda hanya memilih bidang, tempat indeks dibuat, alih-alih seluruh baris:

EXPLAIN SELECT c1 FROM foo WHERE c1 < 500;

Pemindaian Hanya Indeks akan dilakukan lebih cepat, daripada Pemindaian Indeks karena fakta bahwa tidak perlu membaca baris tabel:lebar=4.

Kesimpulan

  • Seq Scan membaca seluruh tabel
  • Pemindaian Indeks menggunakan indeks untuk pernyataan WHERE dan membaca tabel saat memilih baris
  • Pemindaian Indeks Bitmap menggunakan Pemindaian Indeks dan kontrol pemilihan melalui tabel. Efektif untuk sejumlah besar baris.
  • Pemindaian Hanya Indeks adalah blok tercepat, yang hanya membaca indeks.

Bacaan lebih lanjut:

Optimasi Kueri di PostgreSQL. JELASKAN Dasar – Bagian 3


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apa yang terjadi dengan duplikat saat menyisipkan banyak baris?

  2. Panduan untuk Pgpool untuk PostgreSQL:Bagian Satu

  3. ComboBox.ValueMember dan DisplayMember

  4. bagaimana saya bisa membuat file XML baru dari database yang ada di database PostgreSQL menggunakan java

  5. Pemantauan PostgreSQL Proaktif (Sudut Pengembang Studio/Penasihat)