MySQL MENGOPTIMALKAN semua tabel?


245

MySQL memiliki perintah OPTIMIZE TABLE yang dapat digunakan untuk mendapatkan kembali ruang yang tidak digunakan dalam instalasi MySQL. Apakah ada cara (perintah bawaan atau prosedur tersimpan yang umum) untuk menjalankan pengoptimalan ini untuk setiap tabel dalam basis data dan / atau instalasi server, atau apakah ini sesuatu yang harus Anda skrip sendiri?


11
Berhati-hatilah karena ini tidak perlu mengambil kembali ruang. Jika Anda menggunakan InnoDB dengan satu file (mungkin setup paling umum hari ini) daripada memisahkan file per tabel, Anda masih akan menggunakan jumlah ruang disk yang sama di akhir. Sebenarnya saya telah melihatnya benar-benar menggunakan lebih banyak ruang disk ketika semua dikatakan dan dilakukan. Dengan meja besar, meja tersebut dapat dikunci untuk waktu yang sangat lama juga.
jmichalicek

1
OPTIMIZE TABLEberguna untuk MyISAM. Sekarang Mesin itu akan pergi, kebutuhan OPTIMIZE TABLEakan pergi, terutama kebutuhan untuk mengoptimalkan semua tabel secara berkala.
Rick James

+1 untuk info bagus rick - tetapi mengingat praktik basis data dunia nyata standar, saya tidak akan terkejut jika tabel MyISAM lama tetap ada selama satu dekade lagi
Alan Storm

Jawaban:


410

Anda dapat menggunakannya mysqlcheckuntuk melakukan ini di baris perintah.

Satu basis data:

mysqlcheck -o <db_schema_name>

Semua basis data:

mysqlcheck -o --all-databases

Anda akan merekomendasikan perintah ini untuk dijadwalkan untuk berjalan setidaknya sebulan sekali?
Gaia

11
Hai @ Gaia. Belum tentu. Mengoptimalkan semua tabel pada jadwal yang diberikan tidak menguntungkan bagi semua orang. Lihatlah posting ini dan baca komentar untuk pemikiran yang lebih mendalam tentang topik ini daripada yang dapat saya berikan di ruang terbatas di sini: xaprb.com/blog/2010/02/07/…
Ike Walker

18
penggunaan sederhana:mysqlcheck -u [username] -p[password] -o [database name]
M Rostami

38
Harap diperhatikan bahwa tabel dikunci saat OPTIMIZE sedang dilakukan, yang dapat memakan waktu cukup lama jika tabel menampung banyak data. Jadi, selama suatu tabel dioptimalkan, tidak ada catatan baru yang bisa dimasukkan atau dihapus. Secara umum, MENGOPTIMALKAN semua tabel dari sistem produksi tidak dapat dianggap sebagai operasi sepele.
Werner

2
@ No-Chip Anda dapat mengoptimalkan tabel di klien MySQL menggunakan OPTIMIZE TABLEperintah: dev.mysql.com/doc/refman/5.5/en/optimize-table.html . Misalnya, optimalkan satu tabel seperti ini OPTIMIZE TABLE <your_schema>.<your_table>;:, optimalkan semua tabel dalam skema yang diberikan seperti ini:select concat('OPTIMIZE NO_WRITE_TO_BINLOG TABLE ',table_schema,'.',table_name,';') into outfile '/tmp/optimize_all_tables.sql' from information_schema.tables where table_schema = 'pabeta' and table_type = 'base table'; source /tmp/optimize_all_tables.sql;
Ike Walker

28

Saya membuat skrip 'sederhana' ini:

set @tables_like = null;
set @optimize = null;
set @show_tables = concat("show tables where", ifnull(concat(" `Tables_in_", database(), "` like '", @tables_like, "' and"), ''), " (@optimize:=concat_ws(',',@optimize,`Tables_in_", database() ,"`))");

Prepare `bd` from @show_tables;
EXECUTE `bd`;
DEALLOCATE PREPARE `bd`;

set @optimize := concat('optimize table ', @optimize);
PREPARE `sql` FROM @optimize;
EXECUTE `sql`;
DEALLOCATE PREPARE `sql`;

set @show_tables = null, @optimize = null, @tables_like = null;

Untuk menjalankannya, cukup tempel di IDE SQL yang terhubung ke database Anda.

Perhatikan: kode ini TIDAK AKAN berfungsi pada phpmyadmin.

Bagaimana itu bekerja

Itu menjalankan show tablespernyataan dan menyimpannya dalam pernyataan yang disiapkan. Kemudian menjalankan a optimize tabledi set yang dipilih.

Anda dapat mengontrol tabel mana yang akan dioptimalkan dengan menetapkan nilai yang berbeda di var @tables_like(mis set @tables_like = '%test%';.:).


4
Lingkungan hosting bersama saya tidak memiliki 'mysqlchk' sehingga saya dapat menjalankan ini langsung dari sesi terminal 'mysql'. Terima kasih!
funwhilelost

Sama sama. Saya menggunakan kode ini untuk mengoptimalkan 50 database dan menghabiskan waktu seminimal mungkin. Jika Anda pikir saya dapat meningkatkan kode dengan cara apa pun, silakan dan beri saya saran Anda. Saya akan dengan senang hati memperbaiki kode yang berharga ini.
Ismael Miguel

Mempersiapkan bddari @b Kode Kesalahan: 1064. Anda memiliki kesalahan dalam sintaks SQL Anda; periksa manual yang sesuai dengan versi server MySQL Anda untuk sintaks yang tepat untuk digunakan di dekat 'NULL' pada baris 1
Paul Gregoire

@ IsmaelMiguel ini adalah MySQL, jawaban Anda menggunakan sintaks TSQL dan tidak akan bekerja dengan MySQL.
Phrancis

2
@LorenzoBelfanti Terima kasih telah mengonfirmasinya. Saya senang, bahkan setelah 2 tahun, kode ini berguna untuk, setidaknya, 10 orang. Itu adalah kemenangan besar bagi saya! Sekali lagi terima kasih!
Ismael Miguel

20

Contoh skrip php berikut dapat membantu Anda mengoptimalkan semua tabel di basis data Anda

<?php

dbConnect();

$alltables = mysql_query("SHOW TABLES");

while ($table = mysql_fetch_assoc($alltables))
{
   foreach ($table as $db => $tablename)
   {
       mysql_query("OPTIMIZE TABLE '".$tablename."'")
       or die(mysql_error());

   }
}

?>

7
Pada database dengan 200 tabel, Anda akan menjalankan 200 kueri terpisah yang mengoptimalkan 1 tabel sekaligus. Anda harus memasukkan nama tabel menjadi satu string dan karenanya hanya satu permintaan tabel optimal diperlukan.
Dean Marshall

8
Saya ingin tahu apakah pendekatan kueri terpisah terkadang lebih baik. MySQL mengatakan bahwa tabel terkunci sementara OPTIMIZE TABLE sedang berjalan. Maka akan lebih bijaksana untuk mengoptimalkan masing-masing pada satu waktu untuk membiarkan server memperoleh kunci untuk waktu minimum. Jelas itu untuk server yang terus diakses. Jika tidak, maka saya pikir satu query mengeluarkan pendekatan terbaik.
glarrain

Akan seperti apa script jika Anda meledak dan dibuat menjadi 1 query? Terima kasih.
H. Ferrence

8
@Dean Pendekatan permintaan terpisah seringkali lebih baik untuk memberikan ruang bernafas untuk aplikasi langsung. Bahkan, saya biasanya menambahkan penundaan (hanya 750 ms atau lebih) untuk tujuan itu.
zanlok

15

Lakukan semua prosedur yang diperlukan untuk memperbaiki semua tabel di semua database dengan skrip shell sederhana:

#!/bin/bash
mysqlcheck --all-databases
mysqlcheck --all-databases -o
mysqlcheck --all-databases --auto-repair
mysqlcheck --all-databases --analyze

11

untuk semua basis data:

mysqlcheck -Aos -uuser -p 

Untuk satu optimasi Database:

mysqlcheck -os -uroot -p dbtest3

Setidaknya bagi saya, di Linux, perintah mysqlcheck -Aostidak memerlukan kata sandi pengguna +.
Zuul

7

Dari phpMyAdmin dan sumber lain yang dapat Anda gunakan:

SET SESSION group_concat_max_len = 99999999;
SELECT GROUP_CONCAT(concat('OPTIMIZE TABLE `', table_name, '`;') SEPARATOR '') AS O
FROM INFORMATION_SCHEMA.TABLES WHERE 
TABLE_TYPE = 'BASE TABLE'
AND table_name!='dual'
AND TABLE_SCHEMA = '<your databasename>'

Kemudian Anda dapat menyalin & menempelkan hasilnya ke kueri baru atau menjalankannya dari sumber Anda sendiri. Jika Anda tidak melihat keseluruhan pernyataan: cara untuk melihat seluruh pernyataan di phpmyadmin


itu jawaban yang bagus, tapi phpmyadmin saya tidak menunjukkan seluruh perintah, hanya yang pertama saja ... sedih untuk saya, lol.
MonneratRJ

6

Jika Anda ingin menganalisis, memperbaiki, dan mengoptimalkan semua tabel di semua database di server MySQL Anda, Anda bisa melakukan ini dalam sekali jalan dari baris perintah. Anda perlu root untuk melakukannya.

mysqlcheck -u root -p --auto-repair --optimize --all-databases

Setelah Anda menjalankannya, Anda akan diminta untuk memasukkan kata sandi root MySQL Anda. Setelah itu, itu akan mulai dan Anda akan melihat hasilnya seperti yang terjadi.

Contoh output:

yourdbname1.yourdbtable1       OK
yourdbname2.yourdbtable2       Table is already up to date
yourdbname3.yourdbtable3
note     : Table does not support optimize, doing recreate + analyze instead
status   : OK

etc..
etc...

Repairing tables
yourdbname10.yourdbtable10
warning  : Number of rows changed from 121378 to 81562
status   : OK

Jika Anda tidak mengetahui kata sandi root dan menggunakan WHM, Anda dapat mengubahnya dari dalam WHM dengan masuk ke: Beranda> Layanan SQL> Kata Sandi Root MySQL


5

Dari baris perintah:

mysqlcheck -o <db_name> -u<username> -p

lalu ketikkan kata sandi


4

Anda dapat mengoptimalkan / memeriksa dan memperbaiki semua tabel database, menggunakan klien mysql.

Pertama, Anda harus mendapatkan semua daftar tabel, dipisahkan dengan ',':

mysql -u[USERNAME] -p[PASSWORD] -Bse 'show tables' [DB_NAME]|xargs|perl -pe 's/ /,/g'

Sekarang, ketika Anda memiliki semua daftar tabel untuk optimasi:

mysql -u[USERNAME] -p[PASSWORD] -Bse 'optimize tables [tables list]' [DB_NAME]

3

Bagian MySQL Administrator(dari Alat MySQL GUI) dapat melakukannya untuk Anda pada tingkat database.

Cukup pilih skema Anda dan tekan Maintenancetombol di sudut kanan bawah.

Karena Alat GUI telah mencapai status Akhir Masa, mereka sulit ditemukan di halaman mysql. Menemukan mereka melalui Google: http://dev.mysql.com/downloads/gui-tools/5.0.html

Saya tidak tahu apakah MySQL Workbench yang baru dapat melakukannya juga.

Dan Anda dapat menggunakan mysqlcheckalat baris perintah yang seharusnya bisa melakukan itu juga.


2

Jika Anda mengakses database secara langsung maka Anda dapat menulis kueri berikut:

OPTIMIZE TABLE table1,table2,table3,table4......;

1

Skrip bash ini akan menerima kata sandi root sebagai opsi dan mengoptimalkannya satu per satu, dengan output status:

#!/bin/bash

if [ -z "$1" ] ; then
  echo
  echo "ERROR: root password Parameter missing."
  exit
fi
MYSQL_USER=root
MYSQL_PASS=$1
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
TBLLIST=""
COMMA=""
SQL="SELECT CONCAT(table_schema,'.',table_name) FROM information_schema.tables WHERE"
SQL="${SQL} table_schema NOT IN ('information_schema','mysql','performance_schema')"
for DBTB in `mysql ${MYSQL_CONN} -ANe"${SQL}"`
do
    echo OPTIMIZE TABLE "${DBTB};"
    SQL="OPTIMIZE TABLE ${DBTB};"
    mysql ${MYSQL_CONN} -ANe"${SQL}"
done

1

Skrip bash pemula untuk membuat daftar dan menjalankan alat melawan DBs ...

#!/bin/bash

declare -a dbs
unset opt

for each in $(echo "show databases;" | mysql -u root) ;do

        dbs+=($each)

done



echo " The system found [ ${#dbs[@]} ] databases." ;sleep 2
echo
echo "press 1 to run a check"
echo "press 2 to run an optimization"
echo "press 3 to run a repair"
echo "press 4 to run check,repair, and optimization"
echo "press q to quit"
read input

case $input in
        1) opt="-c"
        ;;
        2) opt="-o"
        ;;
        3) opt="-r"
        ;;
        4) opt="--auto-repair -c -o"
        ;;
        *) echo "Quitting Application .."; exit 7
        ;;
esac

[[ -z $opt ]] && exit 7;

echo " running option:  mysqlcheck $opt in 5 seconds  on all Dbs... "; sleep 5

for ((i=0; i<${#dbs[@]}; i++)) ;do
        echo "${dbs[$i]} : "
        mysqlcheck $opt ${dbs[$i]}  -u root
    done

0

2 sen saya: mulai dengan tabel dengan fragmentasi tertinggi

for table in `mysql -sss -e "select concat(table_schema,".",table_name) from information_schema.tables where table_schema not in ('mysql','information_schema','performance_schema') order by data_free desc;"
do
mysql -e "OPTIMIZE TABLE $table;"
done
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.