MySQL Alle Tabellen OPTIMIEREN?

245

MySQL verfügt über einen Befehl OPTIMIZE TABLE, mit dem nicht verwendeter Speicherplatz in einer MySQL-Installation zurückgefordert werden kann. Gibt es eine Möglichkeit (integrierter Befehl oder allgemeine gespeicherte Prozedur), diese Optimierung für jede Tabelle in der Datenbank- und / oder Serverinstallation auszuführen, oder müssten Sie diese selbst skripten?

Alan Storm
quelle
11
Seien Sie vorsichtig, da dies nicht unbedingt Speicherplatz beansprucht. Wenn Sie InnoDB mit einer einzelnen Datei verwenden (wahrscheinlich das derzeit am häufigsten verwendete Setup), anstatt Dateien pro Tabelle zu trennen, wird am Ende immer noch dieselbe Menge an Speicherplatz verwendet. Tatsächlich habe ich gesehen, dass es tatsächlich deutlich mehr Speicherplatz beansprucht, wenn alles gesagt und getan wurde. Bei großen Tischen kann der Tisch auch sehr lange gesperrt sein.
Jmichalicek
1
OPTIMIZE TABLEwar nützlich für MyISAM. Jetzt, da diese Engine weg ist, verschwindet die Notwendigkeit OPTIMIZE TABLE, insbesondere die Notwendigkeit, alle Tabellen regelmäßig zu optimieren.
Rick James
+1 für einen guten Info-Rick - aber angesichts der üblichen Datenbankpraktiken in der realen Welt wäre ich nicht überrascht, wenn alte MyISAM-Tabellen noch ein weiteres Jahrzehnt bestehen würden
Alan Storm

Antworten:

410

Sie können mysqlcheckdies in der Befehlszeile tun.

Eine Datenbank:

mysqlcheck -o <db_schema_name>

Alle Datenbanken:

mysqlcheck -o --all-databases
Ike Walker
quelle
Würden Sie empfehlen, diesen Befehl mindestens einmal im Monat auszuführen?
Gaia
11
Hallo @Gaia. Nicht unbedingt. Die Optimierung aller Tabellen nach einem bestimmten Zeitplan ist nicht für alle von Vorteil. Schauen Sie sich diesen Beitrag an und lesen Sie die Kommentare, um mehr über dieses Thema zu erfahren,
Ike Walker
18
einfache Verwendung:mysqlcheck -u [username] -p[password] -o [database name]
M Rostami
38
Bitte beachten Sie, dass Tabellen während der Ausführung von OPTIMIZE gesperrt sind. Dies kann eine beträchtliche Zeit in Anspruch nehmen, wenn die Tabellen viele Daten enthalten. Während der OPTIMIERUNG einer Tabelle können keine neuen Datensätze eingefügt oder gelöscht werden. Im Allgemeinen kann das OPTIMIEREN aller Tabellen eines Produktionssystems nicht als triviale Operation betrachtet werden.
Werner
2
@ No-Chip Sie können Tabellen im MySQL-Client mit dem folgenden OPTIMIZE TABLEBefehl optimieren : dev.mysql.com/doc/refman/5.5/en/optimize-table.html . Optimieren Sie beispielsweise eine Tabelle wie folgt: OPTIMIZE TABLE <your_schema>.<your_table>;Optimieren Sie alle Tabellen in einem bestimmten Schema wie folgt: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

Ich habe dieses 'einfache' Skript erstellt:

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;

Fügen Sie es zum Ausführen einfach in eine beliebige SQL-IDE ein, die mit Ihrer Datenbank verbunden ist.

Hinweis: Dieser Code funktioniert nicht mit phpmyadmin.

Wie es funktioniert

Es führt eine show tablesAnweisung aus und speichert sie in einer vorbereiteten Anweisung. Dann wird ein optimize tableim ausgewählten Satz ausgeführt.

Sie können steuern, welche Tabellen optimiert werden sollen, indem Sie in der Variable einen anderen Wert festlegen @tables_like(z set @tables_like = '%test%';. B. :) .

Ismael Miguel
quelle
4
In meiner gemeinsam genutzten Hosting-Umgebung ist 'mysqlchk' nicht verfügbar, sodass ich dies direkt von einer 'mysql'-Terminalsitzung aus ausführen kann. Danke dir!
Funwhilelost
Bitte schön. Ich verwende diesen Code, um 50 Datenbanken zu optimieren und so wenig Zeit wie möglich zu verbringen. Wenn Sie glauben, dass ich den Code auf irgendeine Weise verbessern kann, geben Sie mir Ihre Vorschläge. Gerne verbessere ich diesen wertvollen Code.
Ismael Miguel
Vorbereiten bdaus @b Fehlercode: 1064. Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion entspricht, auf die richtige Syntax für die Verwendung in der Nähe von 'NULL' in Zeile 1
Paul Gregoire,
@IsmaelMiguel Dies ist MySQL. Ihre Antwort verwendet die TSQL-Syntax und funktioniert nicht mit MySQL.
Phrancis
2
@ LorenzoBelfanti Vielen Dank für die Bestätigung. Ich bin froh, dass dieser Code auch nach 2 Jahren für mindestens 10 Personen nützlich ist. Das ist ein großer Sieg für mich! Nochmals vielen Dank!
Ismael Miguel
20

Das folgende Beispiel-PHP-Skript kann Ihnen helfen, alle Tabellen in Ihrer Datenbank zu optimieren

<?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());

   }
}

?>
Scherbius.com
quelle
7
In einer Datenbank mit 200 Tabellen werden 200 separate Abfragen ausgeführt, wobei jeweils 1 Tabelle optimiert wird. Sie sollten die Tabellennamen in eine Zeichenfolge implodieren. Daher ist nur eine Abfrage zur Optimierung der Tabelle erforderlich.
Dean Marshall
8
Ich frage mich, ob der separate Abfrageansatz manchmal besser ist. MySQL sagt, dass die Tabellen gesperrt sind, während OPTIMIZE TABLE ausgeführt wird. Dann erscheint es klüger, jedes einzeln zu optimieren, damit der Server für die minimale Zeit Sperren erhält. Dies gilt natürlich für einen Server, auf den weiterhin zugegriffen wird. Wenn nicht, dann denke ich, dass eine einzelne Abfrage den besten Ansatz darstellt.
Glarrain
Wie würde das Skript aussehen, wenn Sie implodieren und eine Abfrage erstellen würden? Vielen Dank.
H. Ferrence
8
@Dean Der separate Abfrageansatz ist häufig besser, um einer Live-Anwendung Raum zum Atmen zu geben. Tatsächlich füge ich normalerweise eine Verzögerung (nur etwa 750 ms) für genau diesen Zweck hinzu.
Zanlok
15

Führen Sie alle erforderlichen Schritte aus, um alle Tabellen in allen Datenbanken mit einem einfachen Shell-Skript zu reparieren:

#!/bin/bash
mysqlcheck --all-databases
mysqlcheck --all-databases -o
mysqlcheck --all-databases --auto-repair
mysqlcheck --all-databases --analyze
Ivan Velkov
quelle
11

für alle Datenbanken:

mysqlcheck -Aos -uuser -p 

Für eine Datenbankoptimierung:

mysqlcheck -os -uroot -p dbtest3
Muni
quelle
Zumindest für mich mysqlcheck -Aoserfordert der Befehl unter Linux keinen Benutzer + Passwort.
Zuul
7

Aus phpMyAdmin und anderen Quellen können Sie verwenden:

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

Anschließend können Sie das Ergebnis kopieren und in eine neue Abfrage einfügen oder aus Ihrer eigenen Quelle ausführen. Wenn Sie nicht die ganze Aussage sehen: Weg, um ganze Aussage in phpmyadmin zu sehen

Frank
quelle
das war eine nette antwort, aber mein phpmyadmin zeigt nicht den ganzen befehl, nur die ersten dann ... traurig für mich, lol.
MonneratRJ
6

Wenn Sie alle Tabellen in allen Datenbanken Ihres MySQL-Servers analysieren, reparieren und optimieren möchten, können Sie dies auf einmal über die Befehlszeile tun. Sie benötigen jedoch root, um dies zu tun.

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

Sobald Sie dies ausführen, werden Sie aufgefordert, Ihr MySQL-Root-Passwort einzugeben. Danach startet es und Sie sehen die Ergebnisse, während es passiert.

Beispielausgabe:

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

Wenn Sie das Root-Passwort nicht kennen und WHM verwenden, können Sie es in WHM ändern, indem Sie zu: Home> SQL Services> MySQL-Root-Passwort gehen

Chris
quelle
5

Über die Befehlszeile:

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

Geben Sie dann das Passwort ein

si le
quelle
4

Mit dem MySQL-Client können Sie alle Datenbanktabellen optimieren / überprüfen und reparieren.

Zuerst sollten Sie alle Tabellenlisten erhalten, getrennt durch ',':

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

Wenn Sie nun alle Tabellen zur Optimierung haben:

mysql -u[USERNAME] -p[PASSWORD] -Bse 'optimize tables [tables list]' [DB_NAME]
Victor Driantsov
quelle
3

Der MySQL Administrator(Teil der MySQL GUI Tools) kann dies auf Datenbankebene für Sie erledigen.

Wählen Sie einfach Ihr Schema aus und klicken Sie auf die MaintenanceSchaltfläche in der unteren rechten Ecke.

Da die GUI-Tools den Status "End-of-Life" erreicht haben, sind sie auf der MySQL-Seite schwer zu finden. Gefunden über Google: http://dev.mysql.com/downloads/gui-tools/5.0.html

Ich weiß nicht, ob die neue MySQL Workbench das auch kann.

Und Sie können das mysqlcheckKommandozeilen-Tool verwenden, das dies auch kann.

Jürgen Steinblock
quelle
2

Wenn Sie direkt auf die Datenbank zugreifen, können Sie folgende Abfrage schreiben:

OPTIMIZE TABLE table1,table2,table3,table4......;
Anand Agrawal
quelle
1

Dieses Bash-Skript akzeptiert das Root-Passwort als Option und optimiert es nacheinander mit Statusausgabe:

#!/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
rubo77
quelle
1

Ein Starter-Bash-Skript zum Auflisten und Ausführen eines Tools für die 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
Mike Q.
quelle
0

Meine 2 Cent: Beginnen Sie mit der Tabelle mit der höchsten Fragmentierung

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
DBHash.com
quelle