MySQL OPTIMIZE всіх таблиць?


245

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


11
Будьте уважні, що це не обов'язково поверне місце. Якщо ви використовуєте InnoDB з одним файлом (мабуть, найпоширенішим налаштуванням сьогодні), а не окремими файлами в таблиці, ви все одно будете використовувати однакову кількість місця на диску в кінці. Насправді я бачив, що він фактично використовує значно більше місця на диску, коли все було сказано і зроблено. З великими таблицями стіл може бути заблокований також дуже довго.
jmichalicek

1
OPTIMIZE TABLEбув корисним для MyISAM. Тепер, коли цей двигун згасає, потреба в OPTIMIZE TABLEвідпадає, особливо необхідність періодичної оптимізації всіх таблиць.
Рік Джеймс

+1 за добрий інформаційний рик - але, враховуючи стандартні практики реальних баз даних, я не здивуюся, якщо старі таблиці MyISAM залишаться ще протягом десятиліття
Алан Шторм,

Відповіді:


410

Ви можете використовувати mysqlcheckце в командному рядку.

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

mysqlcheck -o <db_schema_name>

Усі бази даних:

mysqlcheck -o --all-databases

Ви б рекомендували цю команду планувати виконувати принаймні раз на місяць?
Гая

11
Привіт @Gaia Не обов'язково. Оптимізація всіх таблиць за заданим графіком корисна не для всіх. Подивіться на цю публікацію та прочитайте коментарі, щоб набагато глибше поміркувати
Айк Уокер

18
просте використання:mysqlcheck -u [username] -p[password] -o [database name]
M Rostami

38
Будь ласка, майте на увазі, що таблиці блокуються під час виконання програми OPTIMIZE, що може зайняти значний час, якщо таблиці містять багато даних. Таким чином, під час використання таблиці OPTIMIZE'd не можна вставляти чи видаляти нові записи. Взагалі, ОПТИМІЗУВАННЯ всіх таблиць виробничої системи не може розглядатися як тривіальна операція.
Вернер

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;
Ike Walker

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вибраний набір.

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


4
У моєму середовищі спільного хостингу немає "mysqlchk", тому я можу запустити це безпосередньо з термінальної сесії "mysql". Дякую!
funtimelost

Будь ласка. Я використовую цей код, щоб оптимізувати 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());

   }
}

?>

7
У базі даних з 200 таблицями ви будете виконувати 200 окремих запитів, оптимізуючи по 1 таблиці за один раз. Вам слід імпортувати назви таблиць в один рядок, а значить, потрібен лише один запит на оптимізацію таблиці.
Дін Маршалл

8
Цікаво, чи підходить окремий запит іноді краще. MySQL каже, що таблиці заблоковані під час запуску OPTIMIZE TABLE. Тоді, здавалося б, розумніше оптимізувати кожен за один раз, щоб сервер міг придбати блокування за мінімальний час. Очевидно, що це для сервера, до якого зберігається доступ. Якщо ні, то я думаю, що один запит - це найкращий підхід.
glarrain

Як виглядав би сценарій, якби ви імплантувались і перетворювались на 1 запит? Дякую.
Х. Ферренс

8
@Dean Окремий підхід до запитів часто краще надавати місця для дихання для програми. Насправді я зазвичай додаю затримку (всього 750 мс або близько) саме для цієї мети.
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 

Для однієї оптимізації бази даних:

mysqlcheck -os -uroot -p dbtest3

Принаймні для мене в Linux команда mysqlcheck -Aosне вимагає користувача + пароль.
Зууль

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 не показує всієї команди, лише перші, а потім ... сумно для мене, lol.
MonneratRJ

6

Якщо ви хочете проаналізувати, відремонтувати та оптимізувати всі таблиці у всіх базах даних на вашому сервері MySQL, ви можете зробити це за один раз з командного рядка. Для цього вам знадобиться корінь.

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

Якщо ви не знаєте кореневого пароля та використовуєте WHM, ви можете змінити його зсередини WHM, перейшовши до: Головна> Служби SQL> Корінний пароль MySQL


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

The 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 прийме корінний пароль як варіант та оптимізує його один за одним із вихідним статусом

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

Сценарій початкової програми для списку та запуску інструменту проти БД ...

#!/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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.