MySQL оптимизирует все таблицы?

245

MySQL имеет команду OPTIMIZE TABLE, которая может использоваться для освобождения неиспользуемого пространства при установке MySQL. Есть ли способ (встроенная команда или обычная хранимая процедура), чтобы запустить эту оптимизацию для каждой таблицы в базе данных и / или при установке сервера, или это то, что вам нужно было бы написать самому?

Алан Сторм
источник
11
Будьте осторожны в том, что это не обязательно освободит место. Если вы используете InnoDB с одним файлом (вероятно, наиболее распространенной настройкой в ​​наши дни), а не с отдельными файлами на таблицу, в конце вы все равно будете использовать тот же объем дискового пространства. На самом деле я видел, как он фактически использовал значительно больше дискового пространства, когда все было сказано и сделано. С большими столами стол может быть заблокирован на очень долгое время.
jmichalicek
1
OPTIMIZE TABLEбыл полезен для MyISAM. Теперь, когда этот движок уходит, необходимость OPTIMIZE TABLEуходит, особенно необходимость периодически оптимизировать все таблицы.
Рик Джеймс
+1 за хорошую информацию, но учитывая стандартную практику работы с базами данных, я не удивлюсь, если старые таблицы MyISAM будут существовать еще десятилетие
Alan Storm,

Ответы:

410

Вы можете использовать mysqlcheckдля этого в командной строке.

Одна база данных:

mysqlcheck -o <db_schema_name>

Все базы данных:

mysqlcheck -o --all-databases
Айк Уокер
источник
Вы бы порекомендовали запуск этой команды хотя бы раз в месяц?
Гайя
11
Привет @ Гая. Не обязательно. Оптимизация всех таблиц по заданному графику не выгодна для всех. Взгляните на этот пост и прочитайте комментарии для более глубокого размышления на эту тему, чем я могу предоставить здесь в ограниченном пространстве: xaprb.com/blog/2010/02/07/…
Айк Уокер
18
простое использование:mysqlcheck -u [username] -p[password] -o [database name]
М Ростами
38
Обратите внимание, что таблицы блокируются во время выполнения OPTIMIZE, что может занять значительное время, если таблицы содержат много данных. Таким образом, в то время, когда таблица выполняется в режиме OPTIMIZE, новые записи не могут быть вставлены или удалены. Как правило, ОПТИМИЗАЦИЯ всех таблиц производственной системы не может рассматриваться как тривиальная операция.
Вернер
2
@ No-Chip, вы можете оптимизировать таблицы в клиенте MySQL, используя OPTIMIZE TABLEкоманду: dev.mysql.com/doc/refman/5.5/en/optimize-table.html . Например, оптимизируйте одну таблицу следующим образом: 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в выбранном наборе.

Вы можете контролировать, какие таблицы оптимизировать, установив другое значение в переменной @tables_like(например:) set @tables_like = '%test%';.

Исмаэль Мигель
источник
4
В моей среде общего хостинга нет «mysqlchk», поэтому я мог запустить ее непосредственно из сеанса терминала «mysql». Спасибо!
funmostlost
Добро пожаловать. Я использую этот код для оптимизации 50 баз данных и провожу как можно меньше времени. Если вы думаете, что я могу улучшить код каким-либо образом, продолжайте и дайте мне свои предложения. Я буду рад улучшить этот драгоценный кусок кода.
Исмаэль Мигель
Приготовьтесь bdиз @b Код ошибки: 1064. У вас ошибка в синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования рядом с 'NULL' в строке 1
Пол Грегуар
@IsmaelMiguel это MySQL, ваш ответ использует синтаксис TSQL и не будет работать с MySQL.
Фрэнсис
2
@LorenzoBelfanti Спасибо за подтверждение. Я рад, что даже через 2 года этот код будет полезен как минимум для 10 человек. Это огромная победа для меня! Еще раз спасибо!
Исмаэль Мигель
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());

   }
}

?>
Scherbius.com
источник
7
В базе данных с 200 таблицами вы собираетесь выполнить 200 отдельных запросов, оптимизируя по 1 таблице за раз. Вы должны внедрить имена таблиц в одну строку, и, следовательно, требуется только один запрос оптимизации таблицы.
Дин Маршалл,
8
Интересно, лучше ли подход с отдельным запросом? MySQL говорит, что таблицы заблокированы во время работы OPTIMIZE TABLE. Тогда было бы разумнее оптимизировать каждую из них по очереди, чтобы позволить серверу получать блокировки в течение минимального времени. Очевидно это для сервера, к которому постоянно обращаются. Если нет, то я думаю, что один запрос является лучшим подходом.
гларрейн
Как бы выглядел скрипт, если бы вы взорвали и превратили в 1 запрос? Спасибо.
Х. Ферренс,
8
@Dean Подход с использованием отдельных запросов часто лучше, чтобы дать передышку для живого приложения. На самом деле, я обычно добавляю задержку (всего 750 мс или около того) именно для этой цели.
Занлок
15

Выполните все необходимые процедуры для исправления всех таблиц во всех базах данных с помощью простого сценария оболочки:

#!/bin/bash
mysqlcheck --all-databases
mysqlcheck --all-databases -o
mysqlcheck --all-databases --auto-repair
mysqlcheck --all-databases --analyze
Иван Велков
источник
11

для всех баз данных:

mysqlcheck -Aos -uuser -p 

Для одной оптимизации базы данных:

mysqlcheck -os -uroot -p dbtest3
Муни
источник
По крайней мере, для меня, под Linux, команда mysqlcheck -Aosне требует пользователя + пароль.
Zuul
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
6

Если вы хотите проанализировать, исправить и оптимизировать все таблицы во всех базах данных на сервере MySQL, вы можете сделать это за один раз из командной строки. Для этого вам понадобится root.

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

После того, как вы запустите это, вам будет предложено ввести пароль root для MySQL. После этого он запустится, и вы увидите результаты, как это происходит.

Пример вывода:

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, выбрав: Home> SQL Services> MySQL Root Password

Крис
источник
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 примет пароль root в качестве опции и оптимизирует его один за другим с выводом статуса:

#!/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
источник
1

Скрипт стартового 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
Майк Q
источник
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
DBHash.com
источник