2011-03-29 64 views
212

MySQL有一个OPTIMIZE TABLE命令,可用于回收MySQL安装中未使用的空间。有没有一种方法(内置命令或通用存储过程)为数据库和/或服务器安装中的每个表运行此优化,或者您需要自己编写脚本?MySQL优化所有表?

+9

当那小心这不会necessari回收空间。如果您将InnoDB与单个文件(可能是目前最常用的安装程序)一起使用,而不是每个表单独文件,则最终仍会使用相同数量的磁盘空间。事实上,我已经看到,当所有事情都说完之后,它实际上会使用更多的磁盘空间。使用大桌子时,桌子也可能会锁定很长时间。 – jmichalicek 2011-03-29 15:10:22

回答

347

您可以使用mysqlcheck在命令行执行此操作。

一个数据库:

mysqlcheck -o <db_schema_name> 

所有的数据库:

mysqlcheck -o --all-databases 
+0

你会推荐这个命令安排每月至少运行一次吗? – Gaia 2012-10-09 19:35:38

+9

嗨@Gaia。不必要。在给定的时间表上优化所有表格对每个人都没有好处。看看这篇文章,并阅读更多深入思考这个主题的意见,我可以在这里提供有限的空间:http://www.xaprb.com/blog/2010/02/07/how-often-应该使用优化表/ – 2012-10-23 21:19:40

+0

更像“可能不是”,除非你避免使用大型表,并且了解哪些表是InnoDB与MyISAM – zanlok 2012-12-10 17:45:46

14

下面的例子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()); 

    } 
} 

?> 
+5

在包含200个表的数据库上,您将运行200个单独的查询,一次优化1个表。您应该将表名解析为一个字符串,因此只需要一个优化表查询。 – 2012-04-14 11:23:54

+0

好点院长 – 2012-08-17 02:14:00

+7

我想知道单独的查询方法是否有时更好。 MySQL表示在OPTIMIZE TABLE运行时表格被锁定。然后,每次优化每个服务器让服务器在最短时间内获取锁定似乎更为明智。很明显,这是一个不断被访问的服务器。如果不是,那么我认为单个查询是最好的方法。 – glarrain 2012-09-06 14:45:47

3

MySQL Administrator(MySQL的GUI工具的一部分),可以为你做的数据库级别。

只需选择您的架构并按下右下角的Maintenance按钮即可。

由于GUI Tools已达到报废状态,因此很难在mysql页面上找到它们。通过Google找到它们:http://dev.mysql.com/downloads/gui-tools/5.0.html

我不知道新的MySQL Workbench是否也可以这样做。

而且您也可以使用mysqlcheck命令行工具,该工具也应该可以这样做。

4

从命令行:

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

然后键入密码

4

您可以优化/检查和修复所有表o f数据库,使用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] 
9

所有数据库:

mysqlcheck -Aos -uuser -p 

对于一个数据库的优化:

mysqlcheck -os -uroot -p dbtest3 
+0

至少对我来说,在Linux下,命令'mysqlcheck -Aos'不需要用户名+密码。 – Zuul 2017-11-13 15:03:59

19

我做了这个“简单”的脚本:

set @a=null,@c=null,@b=concat("show tables where",ifnull(concat(" `Tables_in_",database(),"` like '",@c,"' and"),'')," (@a:=concat_ws(',',@a,`Tables_in_",database(),"`))"); 

Prepare `bd` from @b; 
EXECUTE `bd`; 
DEALLOCATE PREPARE `bd`; 

set @a:=concat('optimize table ',@a); 
PREPARE `sql` FROM @a; 
EXECUTE `sql`; 
DEALLOCATE PREPARE `sql`; 

set @a=null,@b=null,@c=null; 

要运行它,只需将其粘贴在连接到数据库的任何SQL IDE。

注意:此代码对phpmyadmin不起作用

它是如何工作

它运行在一份声明中一个show tables语句和存储。然后在选定的集合中运行optimize table

您可以通过在var @c中设置不同的值来控制要优化哪些表。

+3

我的共享主机环境没有'mysqlchk'可用,所以我可以直接从'mysql'终端会话运行。谢谢! – funwhilelost 2014-03-03 23:00:47

+0

不客气。我使用此代码优化了50个数据库,并尽可能地花费最少的时间。如果您认为我可以通过任何方式改进代码,请继续并提出您的建议。我将很乐意改进这段珍贵的代码。 – 2014-03-03 23:06:05

+0

从@b \t准备'bd'错误代码:1064.您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,以便在第1行'NULL'附近使用正确的语法。 – 2014-04-25 16:30:17

8

是否所有必要的程序固定在所有数据库中的所有表用一个简单的shell脚本:

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

太棒了!自动:) – 2017-11-17 13:04:32

-1

我的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 
4

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

然后你可以复制&将结果粘贴到新查询或从您自己的源执行。

0

这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 
1

如果你要分析,修复和优化你的MySQL服务器中的所有数据库中的所有表,你可以从命令行中一次完成。尽管如此,你仍需要root权限。

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

一旦你运行了,你会被提示输入你的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密码,并使用小南国,您可以将其从内南国通过将改变: 首页> SQL服务> MySQL root密码

0

起动机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