Bagaimana cara menentukan sort_buffer_size optimal?

10

Saya membaca dari file konfigurasi sampel yang mengatakan sebagai berikut:

# Sort buffer is used to perform sorts for some ORDER BY and GROUP BY
# queries. If sorted data does not fit into the sort buffer, a disk
# based merge sort is used instead - See the "Sort_merge_passes"
# status variable. Allocated per thread if sort is needed.

Saya punya beberapa pertanyaan yang menggunakan filesort. Bagaimana cara menentukan ukuran buffer yang saya perlukan agar query dapat berjalan dengan lancar tanpa mengenai disk?

Pertanyaan Melimpah
sumber
Sudahkah Anda menjalankan mysqltuner atau tuning-primer Anda mungkin melihat sesuatu yang menarik tentang my.cnf Anda di aplikasi ini.
David Martinez

Jawaban:

14

Hanya ada satu variabel status yang peduli tentang sort_buffer_size . Itulah yang Anda miliki dalam pesan di pertanyaan: Sort_merge_passes . Dokumentasi MySQL mengatakan:

Sort_merge_passes: Jumlah penggabungan melewati yang harus dilakukan algoritma sortir. Jika nilai ini besar, Anda harus mempertimbangkan untuk meningkatkan nilai variabel sistem sort_buffer_size .

Harap diingat satu hal tentang sort_buffer_size

Jika Anda melihat banyak Sort_merge_passes per detik di SHOW GLOBAL STATUS output, Anda dapat mempertimbangkan untuk meningkatkan nilai sort_buffer_size untuk mempercepat ORDER BY atau operasi GROUP BY yang tidak dapat ditingkatkan dengan optimasi kueri atau pengindeksan yang ditingkatkan

Meskipun meningkatkan sort_buffer_sizedapat membantu kueri dengan GROUP BYs dan ORDER BYs, Anda lebih baik meningkatkan kueri yang dapat Anda tingkatkan dan menambahkan indeks yang dapat digunakan oleh Pengoptimal Kueri.

Pertanyaan tetap: Bagaimana Anda memeriksa Sort_merge_passes ???

Gunakan kode ini, untuk memeriksa berapa banyak Sort_merge_passes yang terjadi dalam 5 menit terakhir. Itu juga menghitung Sort_merge_passes per jam.

SET @SleepTime = 300;
SELECT variable_value INTO @SMP1
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SELECT SLEEP(@SleepTime) INTO @x;
SELECT variable_value INTO @SMP2
FROM information_schema.global_status WHERE variable_name = 'Sort_merge_passes';
SET @SMP = @SMP2 - @SMP1;
SET @SMP_RATE = @SMP * 3600 / @SleepTime;
SELECT @SMP,@SMP_RATE;

Jika Anda menemukan Sort_merge_passes dan nilai terlalu tinggi, jangan ragu untuk meningkatkan sort_buffer_size . Misalkan Anda ingin menaikkan ke 4M. Anda akan menjalankan ini:

mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;

Anda kemudian akan menambahkan ini ke my.cnf

[mysqld]
sort_buffer_size = 4M

Anda akan menjalankan kode secara berkala untuk memeriksa waktu lain Sort_merge_passes paku.

RolandoMySQLDBA
sumber
2
Ini adalah jawaban yang jauh lebih baik
Greg
7
@RolanoMySQLDBA dapatkah Anda mendefinisikan "banyak" sebagai berikut: "Jika Anda melihat banyak Sort_merge_passes per detik"
Tarek
2

Anda tidak perlu mengubah sort_buffer_size dari default. Anda salah paham penggunaannya berdasarkan pertanyaan. Anda harus mulai dengan memeriksa SQL untuk melihat apakah Anda dapat menyelaraskannya dan memenuhi persyaratan ORDER BY / GROUP BY dengan menggunakan indeks. Biasanya akan menjadi indeks komposit.

Lebih lanjut: http://www.xaprb.com/blog/2010/05/09/how-to-tune-mysqls-sort_buffer_size/

eroomydna
sumber
Maaf untuk mengatakan bahwa saya menemukan posting itu hampir tidak berguna. Ini seperti memberi tahu orang-orang untuk tidak melakukan sesuatu hanya karena Anda bukan ahli. Seperti yang ditunjukkan oleh komentator pertama, .cnffile sampel yang dikirim dengan mysql tidak menggunakan pengaturan default.
Pertanyaan Overflow
Jika Anda membacanya lagi itu juga mengatakan bahwa ahli sudah tahu untuk tidak mengubah nilai dari default. File .cnf sampel tidak boleh digunakan atau dirujuk sebagai praktik yang baik. Jika Anda perlu bantuan membangun file my.cnf Percona menawarkan panduan yang cukup menyeluruh. tools.percona.com/wizard
eroomydna
2

Panduan dalam manual (5.0-5.5) adalah

Jika Anda melihat banyak Sort_merge_passes per detik dalam output SHOW GLOBAL STATUS, Anda dapat mempertimbangkan untuk meningkatkan nilai sort_buffer_size untuk mempercepat ORDER BY atau operasi GROUP BY yang tidak dapat ditingkatkan dengan optimasi kueri atau pengindeksan yang ditingkatkan. Seluruh buffer dialokasikan bahkan jika tidak semua dibutuhkan, jadi pengaturannya yang lebih besar dari yang dibutuhkan secara global akan memperlambat sebagian besar permintaan yang menyortir. Yang terbaik adalah meningkatkannya sebagai pengaturan sesi, dan hanya untuk sesi yang membutuhkan ukuran lebih besar. Di Linux, ada ambang 256KB dan 2MB di mana nilai yang lebih besar secara signifikan dapat memperlambat alokasi memori, jadi Anda harus mempertimbangkan untuk tetap di bawah salah satu dari nilai-nilai itu. Eksperimen untuk menemukan nilai terbaik untuk beban kerja Anda.

Dari 5.6 dan seterusnya, kata-kata menunjukkan bahwa pengoptimal dapat memilih nilai untuk kueri dan bahwa server dapat memperluas buffer hingga batas. Ini mengurangi biaya pengaturan nilai terlalu tinggi. Jadi sepertinya Anda mungkin ingin menjadi konservatif, lebih rendah dari standar (Seperti yang dilakukan file cnf rilis) untuk rilis di bawah 5.6.4 tetapi dapat memiliki batas yang lebih tinggi dari mengatakan 2MB default, atau bahkan lebih, dari 5.6. 4 karena jumlah penuh tidak dialokasikan secara membabi buta.

Pada MySQL 5.6.4, pengoptimal mencoba mencari tahu berapa banyak ruang yang dibutuhkan tetapi dapat mengalokasikan lebih banyak, hingga batas.

ClearCrescendo
sumber
1

Cara terbaik untuk menentukan yang optimal sort_buffer_sizeadalah dengan membandingkannya.

Bagaimana? Seperti @RolandoMySQLDBA mengatakan pengecekan Sort_merge_passesmungkin bermanfaat, tapi itu bukan satu-satunya faktor yang mempengaruhi kinerja. Anda harus berhati-hati ketika menambah sort_buffer_size.

Dokumen itu mengatakan itu

Di Linux, ada ambang 256KB dan 2MB di mana nilai yang lebih besar secara signifikan dapat memperlambat alokasi memori, jadi Anda harus mempertimbangkan untuk tetap di bawah salah satu dari nilai-nilai itu.

Ada posting tentang pengujian yang menyimpulkan itu

sort_merge_passestidak seburuk itu. Pengaturan Anda sort_buffer_sizecukup besar sehingga tidak ada nol sort_merge_passesmungkin tidak optimal.

Ketika saya diuji, saya juga mendapatkan hasil yang serupa.

Idealnya, akan lebih baik untuk menghindari situasi yang Anda butuhkan untuk mengoptimalkan sort_buffer_size. Bagaimana? Dokumen ORDER BY Optimization ini dapat membantu Anda memahami bagaimana segala sesuatu bekerja di bawah tenda.

Sanghyun Lee
sumber
-1

"mysql> SET GLOBAL sort_buffer_size = 1024 * 1024 * 4;" ini cara yang buruk untuk memasukkan 4m ukuran penyangga, itulah yang membuat ukuran penyangga menggunakan 4GB

"mysql> SET GLOBAL sort_buffer_size = 1024 * 4;"

Jika saya sudah menjadi milik Anda, saya tidak mencoba mengubah ukuran buffer pendek, itu adalah cara yang baik untuk membuat server Anda crash, dan mengirim kinerja sampah. Lebih baik mencoba membuat querys yang lebih baik.

Moorer
sumber
1
Bagaimana penyortiran besar dapat terjadi dalam buffer penyortiran 4K? Perhatikan bahwa Anda mengatakan 1024 * 4. Itu 4096, 4K.
RolandoMySQLDBA
Apa yang dikatakan Rolando ^^. Dan nilai minimum yang diizinkan adalah 32 ribu.
ypercubeᵀᴹ