MySQL은 모든 테이블을 최적화합니까?


245

MySQL에는 OPTIMIZE TABLE 명령이있어 MySQL 설치에서 사용되지 않은 공간을 회수 할 수 있습니다. 데이터베이스 및 / 또는 서버 설치의 모든 테이블에 대해이 최적화를 실행하는 방법 (내장 명령 또는 공통 저장 프로 시저)이 있습니까? 아니면 직접 스크립트해야합니까?


11
이것이 반드시 공간을 되 찾을 필요는 없다는 점에주의하십시오. 테이블 당 별도의 파일이 아닌 단일 파일 (아마도 가장 일반적인 설정)로 InnoDB를 사용하는 경우에도 여전히 같은 양의 디스크 공간이 사용됩니다. 사실 나는 모든 것이 말되고 완료되었을 때 실제로 훨씬 더 많은 디스크 공간을 사용하는 것을 보았습니다. 큰 테이블의 경우 테이블도 매우 오랫동안 잠겨있을 수 있습니다.
jmichalicek

1
OPTIMIZE TABLEMyISAM에 유용했습니다. 이제 엔진이 OPTIMIZE TABLE사라지고, 특히 모든 테이블을 주기적으로 최적화해야 할 필요성이 사라집니다.
Rick James

정보 릭을 높이기 위해 +1하지만 표준 실제 데이터베이스 관행을 감안할 때 오래된 MyISAM 테이블이 10 년 동안 남아 있다고해도 놀라지 않을 것입니다
Alan Storm

답변:


410

mysqlcheck명령 행에서이를 수행 할 수 있습니다 .

하나의 데이터베이스 :

mysqlcheck -o <db_schema_name>

모든 데이터베이스 :

mysqlcheck -o --all-databases

이 명령을 한 달에 한 번 이상 실행하도록 예약 하시겠습니까?
Gaia

11
@Gaia 님 안녕하세요. 반드시 그런 것은 아닙니다. 주어진 일정에 따라 모든 테이블을 최적화하는 것이 모든 사람에게 도움이되지는 않습니다. :이 게시물에 봐, 그리고 내가 제한된 공간에서 제공 할 수있는 것보다 여기에이 주제에 훨씬 더 깊이 생각에 대한 의견을 읽고 xaprb.com/blog/2010/02/07/...
아이크 워커

18
간단한 사용 :mysqlcheck -u [username] -p[password] -o [database name]
M Rostami

38
OPTIMIZE가 수행되는 동안 테이블이 잠기 므로 테이블에 많은 데이터가 있으면 상당한 시간이 걸릴 수 있습니다. 따라서 테이블이 OPTIMIZE '되는 동안에는 새 레코드를 삽입하거나 삭제할 수 없습니다. 일반적으로 프로덕션 시스템의 모든 테이블을 최적화하는 것은 사소한 작업으로 간주 될 수 없습니다.
Werner

2
@ No-Chip dev.mysql.com/doc/refman/5.5/en/optimize-table.htmlOPTIMIZE TABLE 명령을 사용하여 MySQL 클라이언트에서 테이블을 최적화 할 수 있습니다 . 예를 들어, 다음과 같은 최적화 한 표 : :이 같은 주어진 스키마의 모든 테이블을 최적화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선택한 세트에서 a 를 실행합니다 .

var에 다른 값을 설정하여 최적화 할 테이블을 제어 할 수 있습니다 @tables_like(예 :) set @tables_like = '%test%';.


4
내 공유 호스팅 환경에 'mysqlchk'가 없으므로 'mysql'터미널 세션에서 직접 실행할 수 있습니다. 감사합니다!
funwhilelost

아니에요. 이 코드를 사용하여 50 개의 데이터베이스를 최적화하고 가능한 최소 시간을 소비합니다. 어떤 식 으로든 코드를 향상시킬 수 있다고 생각되면 계속 제안하십시오. 이 귀중한 코드를 개선하게되어 기쁩니다.
Ismael Miguel

bd@b Error Code : 1064에서 준비 하십시오. SQL 구문에 오류가 있습니다. 라인 1의 'NULL'근처에서 올바른 구문을 사용하려면 MySQL 서버 버전에 해당하는 매뉴얼을 확인하십시오.
Paul Gregoire

@IsmaelMiguel 이것은 MySQL이며, 귀하의 답변은 TSQL 구문을 사용하며 MySQL에서는 작동하지 않습니다.
Phrancis

2
@LorenzoBelfanti 확인해 주셔서 감사합니다. 2 년이 지난 후에도이 코드는 적어도 10 명에게 유용합니다. 저에게는 큰 승리입니다! 다시 한번 감사합니다!
Ismael Miguel

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 개의 테이블이있는 데이터베이스에서 한 번에 1 개의 테이블을 최적화하는 200 개의 개별 쿼리를 실행합니다. 테이블 이름을 하나의 문자열로 내포해야하므로 하나의 최적화 테이블 쿼리 만 필요합니다.
Dean Marshall

8
별도의 쿼리 접근 방식이 더 나은지 궁금합니다. MySQL은 OPTIMIZE TABLE이 실행되는 동안 테이블이 잠겨 있다고 말합니다. 그러면 서버가 최소 시간 동안 잠금을 획득 할 수 있도록 한 번에 하나씩 최적화하는 것이 더 현명 해 보일 것입니다. 분명히 그것은 액세스 된 서버를위한 것입니다. 그렇지 않다면 단일 쿼리가 최선의 방법이라고 생각합니다.
glarrain

1 개의 쿼리를 내포하고 작성하면 스크립트는 어떻게 생겼습니까? 감사.
H. Ferrence

8
@Dean 별도의 쿼리 접근 방식이 라이브 애플리케이션을위한 호흡 공간을 제공하는 것이 더 좋습니다. 사실, 나는 보통 정확히 그 목적을 위해 750ms 정도의 지연을 추가합니다.
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사용자 + 비밀번호가 필요하지 않습니다.
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 서버의 모든 데이터베이스에있는 모든 테이블을 분석, 복구 및 최적화하려는 경우 명령 행에서 한 번에 수행 할 수 있습니다. 그래도 루트가 필요합니다.

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

루트 비밀번호를 모르고 WHM을 사용하는 경우 홈> SQL 서비스> MySQL 루트 비밀번호 로 이동하여 WHM 내에서 변경할 수 있습니다.


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 스크립트는 루트 비밀번호를 옵션으로 허용하고 상태 출력을 사용하여 하나씩 비밀번호를 최적화합니다.

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

DB에 대해 도구를 나열하고 실행하는 스타터 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

0

내 2cents : 조각화가 가장 높은 테이블로 시작

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.