Cara mengoptimalkan tabel InnoDB di MySQL

8

Saya telah meneliti bagaimana mengoptimalkan hanya tabel terfragmentasi di MySQL dan meninjau posting ini tentang tabel mengoptimalkan . Ini pada dasarnya melakukan query terhadap database information_schema untuk tabel apa saja dengan data_free > 0dan membangun pernyataan SQL OPTIMIZEhanya untuk tabel tersebut. Saya menjalankan kueri ini dan mengidentifikasi 148 tabel untuk optimisasi. Semua tabel yang diidentifikasi adalah tabel InnoDB. Setelah mengeksekusi script SQL optimasi yang dihasilkan, saya menjalankan kembali script asli untuk mengidentifikasi tabel terfragmentasi dan mengembalikan tabel yang sama persis selama pass pertama.

Saya telah melihat posting yang bertentangan mengenai tabel InnoDB dan OPTIMIZEperintahnya. Beberapa mengatakan bahwa OPTIMIZEitu tidak akan berfungsi dengan tabel InnoDB dan Anda perlu menjalankannya ALTER TABLE table_name ENGINE=INNODB. Yang lain mengatakan bahwa OPTIMIZEsebenarnya memanggil ALTER TABLEperintah ketika mengeksekusi terhadap tabel InnoDB. Dengan mengingat hal itu, saya menjalankan ALTER TABLEperintah terhadap salah satu tabel InnoDB yang diidentifikasi terfragmentasi ( data_free > 0) dan menemukan bahwa data_freetidak berubah setelahnya. Ini masih lebih besar dari 0. Saya juga memulai kembali MySQL dan memeriksanya hanya untuk menemukan hasil yang sama.

Sekarang, kami memiliki beberapa server yang menjalankan MySQL 5.5.29 di organisasi kami dan saya menjalankan kueri terhadap semuanya untuk mengidentifikasi tabel InnoDB dengan DATA_FREE=0 or NULLdan tidak ada yang dikembalikan. Mereka semua lebih besar dari nol.

Saya juga menjalankan OPTIMIZEperintah terhadap beberapa MyISAMtabel di mana DATA_FREElebih besar dari nol dan memverifikasi bahwa itu nol setelahnya.

Adakah yang bisa menjelaskan ini untukku? Apa metode yang tepat untuk menghapus fragmentasi dari tabel InnoDB? Apa metode yang tepat untuk menentukan tabel InnoDB terfragmentasi?

Terima kasih

pengguna3151788
sumber

Jawaban:

9

Saya akan menganggap Anda menggunakan innodb_file_per_tablejawaban ini.

Ada lebih dari satu arti untuk "fragmentasi InnoDB":

  1. .ibd file terfragmentasi, dan sangat besar sedangkan dataset kecil
  2. Halaman indeks terfragmentasi karena ada terlalu banyak halaman yang berisi sedikit data, dalam hal ini mereka bisa digabung.

Silakan pertimbangkan posting ini yang saya tulis beberapa waktu lalu: ini menunjukkan bagaimana setelah membersihkan banyak baris dari tabel besar, file data terfragmentasi (yaitu sangat besar dalam sistem file - ini adalah masalah yang diketahui bahwa file-file ini tidak pernah mengurangi ukurannya). Namun indeks tidak terfragmentasi pada akhir penghapusan: ini karena InnoDB menggabungkan halaman dengan benar karena menjadi kosong (er).

The OPTIMIZEperintah memang tidak berlaku pada InnoDB. Apa yang dilakukannya adalah membangun kembali tabel (persis seperti ALTER). Lihat ini:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

Adapun DATA_FREE: Saya sarankan Anda mengabaikan variabel ini. Sejujurnya, saya telah bekerja dengan tabel InnoDB selama 10bertahun - tahun, dan tidak pernah menemukan nilai ini sangat konsisten dengan apa pun.

Dan sekarang saatnya untuk diskusi nyata: apa sebenarnya yang ingin Anda capai? Kecuali jika basis data Anda benar-benar basi, akan selalu ada fragmentasi. Itu wajar untuk proses menambahkan, menghapus dan memperbarui baris di tabel Anda.

Fragmentasi tidak seburuk itu: ruang kosong dapat diperoleh kembali dengan data baru. Jika meja Anda tidak terlalu besar, lupakan saja semuanya. Untuk tabel yang sangat besar, Anda mungkin mendapatkan beberapa ruang disk dengan mengoptimalkan tabel. Tetapi tanyakan pada diri Anda: seberapa cepat meja akan mencapai fragmentasi yang sama? Satu jam? Satu hari? Seminggu? IMHO dalam semua kasus ini tidak ada gunanya untuk mengoptimalkan tabel.

Namun demikian, jika sebuah tabel besar secara besar-besaran dibersihkan dari data, yang tidak diharapkan untuk kembali, saya semua untuk mengoptimalkannya. Katakanlah Anda menyadari bahwa Anda memiliki beberapa data redundan yang terdiri sekitar 30% dari ukuran tabel Anda. Tentu, akan lebih baik untuk memiliki ruang disk itu kembali.

Intinya: hanya mempertimbangkan masalah ini dengan tabel yang sangat besar; hanya jika Anda memiliki masalah dengan ruang disk.

Shlomi Noach
sumber
Saya setuju bahwa data_free tidak berguna. Ini hanya menghitung ruang dalam "luasan bebas" untuk tablespace yang merupakan metrik mengerikan untuk menghitung fragmentasi. Saya pikir jika Anda tidak menggunakannya innodb_file_per_tablejuga akan menampilkan nilai yang sama untuk setiap tabel di tablespace bersama.
jeremycole