Bagaimana cara meningkatkan kinerja MySQL INSERT dan UPDATE?

14

Pertanyaan ini mungkin bisa ditanyakan di StackOverflow juga, tapi saya akan coba di sini dulu ...

Kinerja pernyataan INSERT dan UPDATE di database kami tampaknya merendahkan dan menyebabkan kinerja yang buruk di aplikasi web kami.

Tabel adalah InnoDB dan aplikasi menggunakan transaksi. Adakah penyesuaian mudah yang bisa saya lakukan untuk mempercepat?

Saya pikir kita mungkin melihat beberapa masalah penguncian, bagaimana saya bisa mengetahuinya?

mmattax
sumber
Lebih baik di dba.stackexchange.com
Pacerier

Jawaban:

25
  1. Periksa apakah perangkat keras dan OS Anda dikonfigurasi dan disetel dengan benar:

    • Sumber masalah (CPU / IO / Memory / Swap Usage). Apakah Anda memiliki banyak TIO? Apakah CPU dimuat? Jika Anda memiliki banyak baca IOP, mungkin Anda tidak memiliki cukup buffer_pool InnoDB. Jika CPU dimuat mungkin pertanyaan Anda melakukan scan tabel penuh alih-alih menggunakan indeks yang tepat.
    • Pengaturan disk / RAID / LVM. Dalam beberapa pengaturan tertentu, LVM striping dapat memberi Anda manfaat dengan menyamakan muatan disk (tanpa hardware RAID, beberapa LUNS terhubung)
    • Penjadwal IO: ketika Anda memiliki pengontrol RAID perangkat keras yang baik, mungkin noop adalah yang terbaik. RedHat melakukan beberapa tes dan mereka berkata, bahwa untuk Oracle (dan DB lainnya) CFQ adalah pilihan terbaik. Anda perlu menjalankan beberapa tolok ukur (seperti tpc-c atau tpc-e) dan memilih, apa yang terbaik untuk perangkat keras Anda.
    • Sistem file yang bagus - ext3 tidak berkinerja baik dalam beban kerja spesifik basis data. Lebih baik adalah XFS atau OCFS2. Anda perlu tolok ukur lagi.
    • Perhatikan, jika sistem Anda menggunakan swap. Menggunakan swap menurunkan kinerja mysql .
  2. Periksa, jika instance MySQL / InnoDB Anda disetel dengan benar:

    • ukuran kumpulan buffer - cache halaman data dalam memori
    • innodb_flush_method = O_DIRECT - hindari buffering IO ganda
    • meningkatkan ukuran file log InnoDB - untuk menulis beban kerja intensif ini dapat meningkatkan kinerja. Tapi ingat: ukuran file log yang lebih besar berarti pemulihan kerusakan yang lebih lama. Terkadang dalam hitungan jam !!!
    • innodb_flush_log_at_trx_commit = 0 atau 2 - Jika Anda tidak khawatir tentang ACID dan dapat kehilangan transaksi untuk satu atau dua detik terakhir.
    • key_buffer_size - sangat penting untuk MyISAM, tetapi digunakan untuk tabel sementara disk.
    • Tonton STATUS INNODB Anda
  3. Analisis beban kerja Anda - tangkap semua kueri Anda untuk memperlambat log dan jalankan mk-query-digest di atasnya. Anda dapat menangkap semua pertanyaan menggunakan tcpdump dan maatkit
    • Pertanyaan apa yang paling banyak menghabiskan waktu server Anda?
    • Apakah ada tabel sementara yang dibuat, terutama tabel sementara yang besar?
    • Belajar, cara menggunakan menjelaskan
    • Apakah aplikasi Anda menggunakan transaksi? Ketika Anda menjalankan kueri dengan autocommit = 1 (default ke MySQL), setiap kueri sisipan / pembaruan memulai transaksi baru, yang melakukan beberapa overhead. Jika memungkinkan, lebih baik menonaktifkan autocommit (dengan python autocommit driver MySQL dinonaktifkan secara default) dan jalankan komit secara manual setelah semua modifikasi dilakukan.
    • Apakah aplikasi Anda membuat serangkaian sisipan ke tabel yang sama dalam satu lingkaran? Load data infileperintah jauh lebih cepat untuk serangkaian sisipan.
    • Ingat: select count(*) from table;jauh lebih lambat untuk innodb daripada untuk myisam.
    • Jenis kueri INSERT / UPDATE apa yang menghabiskan sebagian besar waktu server? Bagaimana mereka dioptimalkan?
    • Periksa, apakah DB Anda memiliki indeks yang tepat dan tambahkan, jika perlu.

Di lingkungan kami, kami memiliki situasi, bahwa satu jenis permintaan pembaruan lambat. Perkiraan waktu untuk menyelesaikan pekerjaan batch adalah 2 hari !!! Setelah menganalisis log slowquery, kami menemukan bahwa jenis permintaan pembaruan ini perlu diselesaikan selama 4 detik. Permintaan tampak seperti ini: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz. Setelah mengonversi kueri pembaruan untuk memilih kueri dan menjalankan menjelaskan pada kueri pemilihan yang kami temukan, bahwa jenis kueri ini tidak menggunakan indeks. Setelah membuat indeks yang tepat, kami telah mengurangi waktu eksekusi permintaan pembaruan menjadi milidetik dan seluruh pekerjaan selesai dalam waktu kurang dari dua jam.

Beberapa tautan bermanfaat:

sumar
sumber
5

Dengan konfigurasi innoDB default, Anda akan dibatasi pada seberapa cepat Anda dapat menulis dan mem-flush transaksi ke disk. Jika Anda dapat mengatasi kehilangan sedikit ACID, bereksperimenlah dengan innodb_flush_log_at_trx_commit. Setel ke 0 untuk menulis dan masukkan log ke disk setiap detik. Setel ke 1 (default) untuk menulis dan membilas setiap komit. Setel ke 2 untuk menulis ke file log setelah setiap komit tetapi siram hanya sekali per detik.

Jika Anda dapat mengatasi kehilangan 1 transaksi, ini bisa menjadi cara yang bagus untuk sangat meningkatkan kinerja menulis.

Juga, perhatikan apa yang dilakukan disk Anda. RAID 10> RAID 5 untuk menulis dengan biaya disk tambahan.

tomchuk
sumber
1

Masalah penguncian akan dicontohkan oleh status koneksi di show full processlist;

Baca my.cnfdan dokumentasi MySQL. Opsi konfigurasi didokumentasikan dengan sangat baik.

Secara umum, Anda ingin diproses dalam memori sebanyak mungkin. Untuk optimasi kueri, itu berarti menghindari tabel sementara. Aplikasi indeks yang tepat.

Tuning akan dikhususkan untuk mesin database pilihan Anda dan arsitektur aplikasi. Ada sumber daya yang substansial yang sudah ada pencarian Internet jauh.

Warner
sumber
0

InnoDB adalah mesin yang cukup bagus. Namun, sangat bergantung pada 'disetel'. Satu hal adalah bahwa jika sisipan Anda tidak dalam urutan peningkatan kunci primer, innoDB bisa memakan waktu sedikit lebih lama dari MyISAM. Ini dapat dengan mudah diatasi dengan menetapkan innodb_buffer_pool_size yang lebih tinggi. Saran saya adalah mengaturnya di 60-70% dari total RAM Anda. Saya menjalankan 4 server seperti itu dalam produksi sekarang, memasukkan sekitar 3,5 juta baris per menit. Mereka sudah memiliki hampir 3 Terabyte. InnoDB itu harus, karena sisipan yang sangat bersamaan. Ada cara lebih lanjut untuk mempercepat sisipan. Dan saya telah membandingkan beberapa.

Ajay Divakaran
sumber