2011-03-29 111 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