Perbedaan kinerja antara MySQL dan PostgreSQL untuk skema / kueri yang sama [ditutup]

20

Saya seorang pemula DBA, dan saya memiliki pengalaman dalam Microsoft SQL Server tetapi saya ingin melompat ke FLOSS.

Saya memulai sebuah perusahaan, dan kami mengembangkan aplikasi (PHP) dengan backend Postgres, dan kami melakukan beberapa pengujian membandingkan dengan MySQL juga. Kami mengamati bahwa MySQL dua kali lebih cepat dari PostgreSQL.

Saya melakukan tes kinerja nyata:

  • Kolom yang sama dalam tabel dengan tipe data kolom yang setara.
  • Jumlah baris yang sama.
  • Indeks yang sama di keduanya (kunci utama disertakan).
  • Beban CPU idle dan mesin Postgres jauh lebih baik.
  • Dan permintaan yang sama (jelas).

Apa yang saya lakukan salah?

PS: Saya membaca banyak "howtos" pada tuning kinerja untuk mesin database.
PS (2): Kami menggunakan InnoDB (satu file per tabel) pada database MySQL.


Hai Mat!

Saya melakukan tiga pertanyaan pilih (dan paling sulit) yang umum.

Pertanyaan tentang disk, tentu saja tidak sama; Di Postgres, ini adalah SSD (hampir tiga kali tercepat).

Data cache MySQL:

+------------------------------+----------------------+
| Variable_name                | Value                |
+------------------------------+----------------------+
| binlog_cache_size            | 32768                |
| have_query_cache             | YES                  |
| key_cache_age_threshold      | 300                  |
| key_cache_block_size         | 1024                 |
| key_cache_division_limit     | 100                  |
| max_binlog_cache_size        | 18446744073709547520 |
| query_cache_limit            | 1048576              |
| query_cache_min_res_unit     | 4096                 |
| query_cache_size             | 16777216             |
| query_cache_type             | ON                   |
| query_cache_wlock_invalidate | OFF                  |
| table_definition_cache       | 256                  |
| table_open_cache             | 64                   |
| thread_cache_size            | 8                    |
+------------------------------+----------------------+

Saya tidak tahu cara melihatnya di PostgreSQL.

Terima kasih sebelumnya.

Javier Valencia
sumber
Maaf untuk bahasa Inggris saya
Javier Valencia
(Bahasa Inggris Anda baik-baik saja.) Apakah Anda melakukan tes memuat, atau hanya pertanyaan individual? Bisakah Anda menunjukkan pengaturan database yang Anda gunakan (terutama hal-hal seperti ukuran cache)? (Disk yang sama dalam kedua kasus saya kira?)
Mat
1
Bisakah Anda memposting kueri dan rencana eksekusi Postgres menggunakan explain analyze. Untuk membuatnya lebih mudah dibaca, Anda dapat mengunggah paket tersebut untuk menjelaskan.depesz.com
a_horse_with_no_name
1
Jika Postgres berjalan pada SSD, Anda hampir pasti harus menyetelpostgresql.conf
a_horse_with_no_name
1
@JavierValencia: jika Anda dapat memperbaiki masalah, harap tambahkan jawaban yang menjelaskan apa yang Anda lakukan sehingga orang lain dapat belajar dari itu. Anda juga dapat menerima jawaban Anda sendiri untuk menandai pertanyaan ini telah diselesaikan
a_horse_with_no_name

Jawaban:

41

MySQL dan PostgreSQL sangat berbeda dalam hal kinerja. Tabel InnoDB dan PostgreSQL dioptimalkan untuk berbagai jenis kueri. Memahami perbedaan-perbedaan ini penting untuk memahami bagaimana cara mendapatkan kinerja yang baik dari keduanya.

Sebagai contoh, mari kita lihat perbedaan yang paling jelas.

PostgreSQL vs MySQL / InnoDB Tabel Struktur dan Apa Artinya Ini Untuk Kinerja

Secara umum, pada beban kerja yang kompleks, PostgreSQL akan lebih cepat, tetapi pada pencarian kunci primer sederhana MySQL dengan InnoDB akan lebih cepat.

Tabel postgreSQL adalah tabel heap. Tidak ada opsi untuk membangun tabel yang bukan tabel tumpukan. The clusterperintah hanya menulis ulang tumpukan diperintahkan oleh indeks yang ditentukan. Indeks kemudian memberikan lokasi tumpukan untuk tupel dengan berbagai nilai. Indeks tidak dapat dilalui dalam urutan fisik, hanya urutan logis sehingga mereka memiliki banyak I / O disk acak saat membaca tabel secara berurutan biasanya berarti banyak I / O disk berurutan, karena Anda dapat membaca tabel dalam urutan fisik. Disk berurutan I / O dapat menggunakan cache baca-depan dan beberapa optimasi tingkat OS lainnya.

Artinya, jika Anda membutuhkan sebagian besar catatan atau lebih dari beberapa halaman, biasanya lebih cepat hanya membaca halaman dari disk. Di sisi lain, pencarian kunci utama untuk sebuah tabel mengharuskan memukul indeks, mencari lokasi dalam file kemudian tekan tabel tumpukan dan tarik catatan. Ini berarti sejumlah keping I / O disk acak.

InnoDB menggunakan pendekatan yang berbeda. Dengan InnoDB, tabel adalah indeks b-tree dengan data aktual di payload indeks. Ini berarti bahwa pencarian kunci primer sudah dapat menarik data dari halaman daun, dan I / O disk yang kurang acak diperlukan untuk ini. Pada saat yang sama, pemindaian indeks membutuhkan melintasi dua indeks alih-alih satu, yang berarti penggunaan indeks apa pun selain kunci primer berakhir lebih lambat dan pemindaian berurutan lebih lambat lagi.

Mendapatkan Diagnosis di PostgreSQL

Saya pikir Anda ingin menggunakan sesuatu seperti:

 EXPLAIN (analyse, buffers, verbose)
 [query];

Itu akan memberi Anda rencana permintaan, perkiraan awal, waktu aktual, penggunaan buffer, dan banyak lagi.

Chris Travers
sumber
4
+1 untuk MENJELASKAN (menganalisis, buffer, verbose)
karmakaze
@ ChrisTravers terima kasih atas jawaban yang bagus! Anda berkata: "... (Sequential Innan) scan lebih lambat". Bisakah Anda jelaskan apa yang Anda maksud dengan pemindaian berurutan dalam konteks ini?
VB_
Terima kasih. Saya akan memodifikasi jawabannya. Pemindaian "Sekuensial" di InnoDB berada dalam urutan indeks-logis sehingga Anda memiliki I / O lebih acak dan tidak ada bantuan dari caching baca-depan.
Chris Travers
Terima kasih atas jawaban yang bagus. Bagi siapa pun yang penasaran dengan postgres internal, saya merekomendasikan posting ini: interdb.jp/pg/pgsql01.html Jelaskan bagaimana Postgres menyimpan data sebagai tumpukan tabel.
hqt