MySQL OPTIMIZAR todas las tablas?


245

MySQL tiene un comando OPTIMIZE TABLE que se puede usar para recuperar espacio no utilizado en una instalación de MySQL. ¿Hay alguna forma (comando incorporado o procedimiento almacenado común) para ejecutar esta optimización para cada tabla en la base de datos y / o instalación del servidor, o es algo que tendría que escribir usted mismo?


11
Tenga cuidado ya que esto no necesariamente reclamará espacio. Si está utilizando InnoDB con un solo archivo (probablemente la configuración más común en estos días) en lugar de archivos separados por tabla, seguirá utilizando la misma cantidad de espacio en disco al final. De hecho, he visto que en realidad usa mucho más espacio en disco cuando todo está dicho y hecho. Con tablas grandes, la mesa también puede estar bloqueada durante mucho tiempo.
jmichalicek

1
OPTIMIZE TABLEfue útil para MyISAM. Ahora que ese motor se va, la necesidad OPTIMIZE TABLEse va, especialmente la necesidad de optimizar periódicamente todas las tablas.
Rick James

+1 para una buena información, pero dadas las prácticas estándar de la base de datos del mundo real, no me sorprendería si las tablas antiguas de MyISAM permanecen durante otra década
Alan Storm

Respuestas:


410

Puede mysqlcheckhacerlo para hacerlo en la línea de comando.

Una base de datos:

mysqlcheck -o <db_schema_name>

Todas las bases de datos:

mysqlcheck -o --all-databases

¿recomendaría que este comando se programe para ejecutarse al menos una vez al mes?
Gaia

11
Hola @Gaia No necesariamente. Optimizar todas las tablas en un horario dado no es beneficioso para todos. Eche un vistazo a esta publicación y lea los comentarios para pensar mucho más en profundidad sobre este tema de lo que puedo proporcionar en un espacio limitado aquí: xaprb.com/blog/2010/02/07/…
Ike Walker

18
uso simple:mysqlcheck -u [username] -p[password] -o [database name]
M Rostami

38
Tenga en cuenta que las tablas se bloquean mientras se realiza OPTIMIZE, lo que puede llevar un tiempo considerable si las tablas contienen muchos datos. Por lo tanto, durante el tiempo que se OPTIMIZA una tabla, no se pueden insertar ni eliminar nuevos registros. En general, OPTIMIZAR todas las tablas de un sistema de producción no puede considerarse una operación trivial.
Werner

2
@ No-Chip puede optimizar tablas en el cliente MySQL usando el OPTIMIZE TABLEcomando: dev.mysql.com/doc/refman/5.5/en/optimize-table.html . Por ejemplo, optimice una tabla como esta: OPTIMIZE TABLE <your_schema>.<your_table>;optimice todas las tablas en un esquema dado como este: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

Hice este script 'simple':

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;

Para ejecutarlo, simplemente péguelo en cualquier IDE de SQL conectado a su base de datos.

Aviso: este código NO funcionará en phpmyadmin.

Cómo funciona

Ejecuta una show tablesdeclaración y la almacena en una declaración preparada. Luego ejecuta a optimize tableen el conjunto seleccionado.

Puede controlar qué tablas optimizar mediante la configuración de un valor diferente en la var @tables_like(por ejemplo:) set @tables_like = '%test%';.


44
Mi entorno de alojamiento compartido no tiene 'mysqlchk' disponible, por lo que podría ejecutar esto directamente desde una sesión de terminal 'mysql'. ¡Gracias!
funwhilelost

De nada. Utilizo este código para optimizar 50 bases de datos y pasar la menor cantidad de tiempo posible. Si crees que puedo mejorar el código de alguna manera, adelante, dame tus sugerencias. Estaré encantado de mejorar esta preciosa pieza de código.
Ismael Miguel

Prepárese a bdpartir del código de error @b: 1064. Tiene un error en su sintaxis SQL; consulte el manual que corresponde a la versión de su servidor MySQL para obtener la sintaxis correcta para usar cerca de 'NULL' en la línea 1
Paul Gregoire

@IsmaelMiguel esto es MySQL, su respuesta usa la sintaxis TSQL y no funcionará con MySQL.
Phrancis

2
@LorenzoBelfanti Gracias por confirmarlo. Estoy convencido de que, incluso después de 2 años, este código es útil para, al menos, 10 personas. ¡Esa es una gran victoria para mí! ¡Una vez mas, Gracias!
Ismael Miguel

20

El siguiente ejemplo de script php puede ayudarlo a optimizar todas las tablas en su base de datos

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

   }
}

?>

77
En una base de datos con 200 tablas, ejecutará 200 consultas separadas optimizando 1 tabla a la vez. Debe implosionar los nombres de las tablas en una cadena y, por lo tanto, solo se requiere una consulta de optimización de tabla.
Dean Marshall

8
Me pregunto si el enfoque de consulta por separado a veces es mejor. MySQL dice que las tablas están bloqueadas mientras OPTIMIZE TABLE se está ejecutando. Entonces parecería más inteligente optimizar cada uno a la vez para permitir que el servidor adquiera bloqueos por el tiempo mínimo. Obviamente eso es para un servidor al que se ha accedido. Si no, entonces creo que una sola consulta es el mejor enfoque.
glarrain

¿Cómo se vería el script si implosionara y se convirtiera en 1 consulta? Gracias.
H. Ferrence

8
@Dean El enfoque de consulta por separado suele ser mejor para dar espacio a la respiración para una aplicación en vivo. De hecho, generalmente agrego un retraso (solo 750 ms aproximadamente) exactamente para ese propósito.
zanlok

15

Realice todos los procedimientos necesarios para arreglar todas las tablas en todas las bases de datos con un simple script de shell:

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

11

para todas las bases de datos:

mysqlcheck -Aos -uuser -p 

Para una optimización de base de datos:

mysqlcheck -os -uroot -p dbtest3

Al menos para mí, bajo Linux, el comando mysqlcheck -Aosno requiere usuario + contraseña.
Zuul

7

Desde phpMyAdmin y otras fuentes puede usar:

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

Luego puede copiar y pegar el resultado en una nueva consulta o ejecutarlo desde su propia fuente. Si no ve la declaración completa: manera de ver toda la declaración en phpmyadmin


esa fue una buena respuesta, pero mi phpmyadmin no muestra todo el comando, solo los primeros, entonces ... triste por mí, jajaja.
MonneratRJ

6

Si desea analizar, reparar y optimizar todas las tablas en todas las bases de datos en su servidor MySQL, puede hacerlo de una sola vez desde la línea de comandos. Sin embargo, necesitarás root para hacer eso.

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

Una vez que ejecute eso, se le pedirá que ingrese su contraseña de root de MySQL. Después de eso, comenzará y verá resultados a medida que suceda.

Salida de ejemplo:

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

Si no conoce la contraseña raíz y está utilizando WHM, puede cambiarla desde WHM yendo a: Inicio> Servicios SQL> Contraseña raíz MySQL


5

Desde la línea de comando:

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

luego escriba la contraseña


4

Puede optimizar / verificar y reparar todas las tablas de la base de datos, utilizando el cliente mysql.

Primero, debe obtener todas las listas de tablas, separadas con ',':

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

Ahora, cuando tenga todas las listas de tablas para la optimización:

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

3

El MySQL Administrator(parte de las herramientas de la GUI de MySQL) puede hacerlo por usted a nivel de base de datos.

Simplemente seleccione su esquema y presione el Maintenancebotón en la esquina inferior derecha.

Como las herramientas de la GUI han alcanzado el estado de fin de vida, son difíciles de encontrar en la página mysql. Los encontré a través de Google: http://dev.mysql.com/downloads/gui-tools/5.0.html

No sé si el nuevo MySQL Workbench también puede hacer eso.

Y puede usar la mysqlcheckherramienta de línea de comandos que también debería poder hacerlo.


2

Si está accediendo a la base de datos directamente, puede escribir la siguiente consulta:

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

1

Este script bash aceptará la contraseña de root como opción y la optimizará una por una, con salida de estado:

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

Un script bash de inicio para enumerar y ejecutar una herramienta contra los DB ...

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

mis 2cents: comience con la tabla con mayor fragmentación

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.