MySQLはすべてのテーブルを最適化しますか?


245

MySQLには、MySQLインストールで未使用のスペースを再利用するために使用できるOPTIMIZE TABLEコマンドがあります。データベースおよび/またはサーバーのインストールのすべてのテーブルに対してこの最適化を実行する方法(組み込みコマンドまたは一般的なストアドプロシージャ)はありますか、それとも自分でスクリプトを作成する必要がありますか?


11
これは必ずしもスペースを再利用するわけではないので注意してください。テーブルごとに個別のファイルではなく、1つのファイル(おそらく最近最も一般的な設定)でInnoDBを使用している場合でも、最後に同じ量のディスク領域を使用します。実際、すべてのことを言って実行すると、実際にはかなり多くのディスク領域を使用することがわかりました。大きなテーブルでは、テーブルが非常に長い時間ロックされることもあります。
jmichalicek 2011年

1
OPTIMIZE TABLEMyISAMに役立ちました。Engineが廃止されたためOPTIMIZE TABLE、特にすべてのテーブルを定期的に最適化する必要性がなくなりました。
リックジェームス

良い情報を得るには+1-しかし、標準の現実世界のデータベースの慣行を考えると、古いMyISAMテーブルがさらに10年間残っていても驚かないでしょう
Alan Storm

回答:


410

mysqlcheckコマンドラインでこれを行うために使用できます。

1つのデータベース:

mysqlcheck -o <db_schema_name>

すべてのデータベース:

mysqlcheck -o --all-databases

このコマンドを少なくとも月に1回実行するようにスケジュールすることをお勧めしますか?
ガイア

11
@Gaiaさん、こんにちは。必ずしも。特定のスケジュールですべてのテーブルを最適化しても、すべての人にメリットがあるわけではありません。この投稿を見てコメントを読んで、このトピックについて、私がここの限られたスペースで提供できるよりも深く考えてください。xaprb.com
Ike Walker

18
簡単な使用:mysqlcheck -u [username] -p[password] -o [database name]
Mロスタミ2013年

38
OPTIMIZEの実行中はテーブルがロックされるため、テーブルに大量のデータが保持されている場合は、かなりの時間がかかる可能性があることに注意してください。したがって、テーブルがOPTIMIZEされている間、新しいレコードを挿入または削除することはできません。一般に、本番システムのすべてのテーブルを最適化することは、簡単な操作とは見なされません。
Werner

2
@ No-Chip OPTIMIZE TABLEコマンドdev.mysql.com/doc/refman/5.5/en/optimize-table.htmlを使用して、MySQLクライアントのテーブルを最適化できます。例えば、このような最適化1つのテーブルには:OPTIMIZE TABLE <your_schema>.<your_table>;:、このような特定のスキーマ内のすべてのテーブルを最適化する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;
アイクウォーカー

28

私はこの「簡単な」スクリプトを作成しました:

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;

実行するには、データベースに接続されているSQL IDEに貼り付けます。

注意:このコードはphpmyadminでは機能ません

使い方

show tablesステートメントを実行し、それを準備済みステートメントに格納します。次にoptimize table、選択したセットでa を実行します。

varに異なる値を設定することで、最適化するテーブルを制御できます@tables_like(例:)set @tables_like = '%test%';


4
私の共有ホスティング環境では「mysqlchk」が利用できないため、「mysql」ターミナルセッションから直接実行できます。ありがとうございました!
funwhilelost 2014

どういたしまして。このコードを使用して50のデータベースを最適化し、可能な限り最小限の時間を費やしています。何らかの方法でコードを改善できると思われる場合は、先に進んで提案をお寄せください。この貴重なコードを改善させていただきます。
Ismael Miguel 14

bd@bエラーコード:1064から準備します。SQL構文にエラーがあります。1行目で「NULL」付近で使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください
Paul Gregoire

@IsmaelMiguelこれはMySQLです。あなたの答えはTSQL構文を使用しており、MySQLでは機能しません。
フランシス2015

2
@LorenzoBelfanti確認ありがとうございます。2年たった後でも、このコードは少なくとも10人にとっては便利です。それは私にとって大きな勝利です!もう一度、ありがとう!
Ismael Miguel

20

次のサンプルphpスクリプトは、データベース内のすべてのテーブルを最適化するのに役立ちます

<?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
200のテーブルがあるデータベースでは、一度に1つのテーブルを最適化する200の個別のクエリを実行します。テーブル名を1つの文字列に分解する必要があるため、最適化テーブルクエリは1つだけ必要です。
ディーンマーシャル

8
別のクエリアプローチの方が良い場合もあるのではないでしょうか。MySQLは、OPTIMIZE TABLEの実行中はテーブルがロックされていると言います。次に、サーバーを最小時間でロックを取得できるように、一度に1つずつ最適化する方が賢明です。明らかにそれはアクセスされ続けるサーバーのためのものです。そうでない場合は、単一のクエリが最善のアプローチだと思います。
グラレイン2012

内破して1つのクエリにした場合、スクリプトはどのようになりますか?ありがとう。
H.フェレンス2012年

8
@Dean個別のクエリアプローチは、多くの場合、ライブアプリケーションに余裕を与えるために優れています。実際、私は通常、まさにその目的のために遅延(わずか750ms程度)を追加します。
zanlok

15

単純なシェルスクリプトを使用して、すべてのデータベースのすべてのテーブルを修正するために必要なすべての手順を実行します。

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

11

すべてのデータベース:

mysqlcheck -Aos -uuser -p 

1つのデータベース最適化の場合:

mysqlcheck -os -uroot -p dbtest3

少なくとも私にとっては、Linuxでは、コマンドにmysqlcheck -Aosuser + passwordは必要ありません。
Zuul 2017年

7

phpMyAdminおよびその他のソースから使用できます。

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>'

次に、結果を新しいクエリにコピーして貼り付けるか、独自のソースから実行できます。ステートメント全体が表示されない場合: phpmyadminでステートメント全体を確認する方法


それはいい答えでしたが、私のphpmyadminはコマンド全体を表示しません。最初のコマンドだけを表示します...私にとっては悲しいです、笑。
MonneratRJ 2019

6

MySQLサーバーのすべてのデータベースのすべてのテーブルを分析、修復、最適化する場合は、コマンドラインから一度に実行できます。ただし、そのためにはrootが必要です。

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

これを実行すると、MySQL rootパスワードの入力を求められます。その後、それが開始され、結果が表示されます。

出力例:

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

rootパスワードがわからず、WHMを使用している場合は、WHM内から次のようにして変更できます。 ホーム> SQLサービス> MySQL Rootパスワード


5

コマンドラインから:

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

次にパスワードを入力します


4

mysqlクライアントを使用して、データベースのすべてのテーブルを最適化/チェックおよび修復できます。

最初に、「、」で区切られたすべてのテーブルリストを取得する必要があります。

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

ここで、最適化のためのすべてのテーブルリストがある場合:

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

3

MySQL Administrator(MySQLのGUIツールの一部)は、データベースレベルであなたのためにそれを行うことができます。

スキーマを選択して、 Maintenanceして、右下ボタンです。

GUIツールがサポート終了に達したため、mysqlページで見つけるのは困難です。Google経由で見つけた:http : //dev.mysql.com/downloads/gui-tools/5.0.html

新しいMySQL Workbenchがそれを実行できるかどうかもわかりません。

そして、あなたは使うことができます mysqlcheckはずのコマンドラインツールを使うこともできます。


2

データベースに直接アクセスしている場合は、次のクエリを記述できます。

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

1

このbashスクリプトは、オプションとしてルートパスワードを受け入れ、ステータス出力とともに1つずつ最適化します。

#!/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

DBに対してツールをリストして実行するためのスターターbashスクリプト...

#!/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セント:断片化が最も高いテーブルから開始

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.