하나의 MySQL 테이블에서 동일한 데이터베이스의 다른 MySQL 테이블로 복사


15

MySQL 테이블에 약 4 천만 개의 행이 있으며이 테이블을 동일한 데이터베이스의 다른 테이블에 복사하려고합니다. 가장 효율적인 방법은 무엇입니까? 시간이 얼마나 걸립니까 (약)?


당신의 테이블의 엔진은 무엇입니까?
압둘 마나프

이노 엔진 ...
Devashish 딕 시트

답변:


23

당신이 mydb.mytb있고 당신이 만들고 싶다고 가정mydb.mytbcopy

이 사본을 작성하는 데 5 가지 방법이 있습니다.

접근법 # 1

에서 mysql클라이언트, 다음을 실행

USE mydb
CREATE TABLE mytbcopy LIKE mytb;
INSERT INTO mytbcopy SELECT * FROM mytb;

접근법 # 2

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb | mysql ${MYSQL_CONN} -Dtest
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

접근법 # 3

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dtest < ${DUMPFILE}
rm -f ${DUMPFILE}
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

접근법 # 4

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

접근법 # 5

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dmydb < ${DUMPFILE}
rm -f ${DUMPFILE}

분석

  • 접근법 # 1 은 단계 측면에서 가장 쉽지만 하나의 트랜잭션으로 4 천만 개의 행을 푸시해야합니다. 이것은 InnoDB 스토리지 엔진에서 가장 많은 과세입니다.
  • 다른 접근 방식의 경우 mysqldump는 수천 행에 4 천만 행을 보냅니다.
    • APPROACH # 2APPROACH # 3 은 테이블을 테스트 데이터베이스로 mysqldump합니다. 테스트 데이터베이스에서 테이블을 생성 한 후 이름이 바뀌고 원래 데이터베이스로 이동됩니다.
    • APPROACH # 4APPROACH # 5 는 INSERT 명령을 에코 할 때 mysqldump에서 나오는 스트림에 대해 sed 를 사용하여 테이블 이름을 바꿉니다.
    • APPROACH # 2APPROACH # 4 는 출력 파일 대신 파이프를 사용합니다.
    • APPROACH # 3APPROACH # 5 는 후속 재로드를 위해 outpuit 파일을 사용합니다.

mydb.mytb기존 테이블 에 복사하려는 경우 mydb.mytbcopy두 테이블의 구조는 동일합니다.

접근법 # 6

INSERT INTO mytbcopy SELECT * FROM mytb;

마찬가지로 #APPROACH 1 , #APPROACH 6 천만 행의 단일 거래를 할 것이다

접근법 # 7

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} -t mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

이 방법은 테이블을 삭제하지 않습니다. 그것은 단순히 INSERT를 생성합니다

발문

DB 서버의 구성, 테이블 구조, 인덱스 레이아웃 및 이와 유사한 것을 모르기 때문에 시간을 예상 할 수 없습니다.

시도 해봐 !!!


0

MyISAM *과 달리 InnoDB 테이블은 데이터 딕셔너리의 일부 (및 병합 버퍼와 같이 테이블이 의존하는 다른 구조)가 메모리 (서버가 실행중인 경우)에 있고 큰 파일 불리는 일명하는 일반 / 메인 테이블, ibdata1.

Percona Server> = 5.1 또는 MySQL> = 5.6을 사용하는 경우, 이동 가능한 테이블 스페이스가 지원되므로 파일 시스템에서 직접 테이블을 내보내고 가져올 수 있습니다. 다음은 MySQLPercona를 위한 방법입니다 . 두 경우 모두, innodb_file_per_table옵션을 사용 하여 테이블을 작성 해야하고 DISCARD TABLESPACE/IMPORT TABLESPACEPercona Xtrabakup 의 사용법 및 / 또는 Percona Xtrabakup 의 사용 이 필요합니다 (내보내기를 온라인으로 수행하려는 경우). Percona Server 또는 Xtrabakup은 Windows에서 사용할 수 없습니다.

이 방법은 일반적으로 파일 시스템 명령 (cp, rsync)을 사용하여 파일 을 복사하는 것만 큼 빠릅니다 .

복원을 위해 MySQL <5.6 (해키 방식)에서 작동 할 수있는 경우가 있지만 테이블 복사에서는 작동하지 않습니다. 이러한 경우 SQL을 사용하는 방법이 있습니다 .

CREATE TABLE new_table LIKE old_table;
INSERT INTO new_table SELECT * FROM old_table;

InnoDB의가 실행할 수있는 이것은 빠른 것 Handler_read_rnd_next하고 Handler_write한 번 행 당. 이 방법을 사용하는 경우 내구성 옵션을 일시적으로 비활성화하고 큰 버퍼 풀과 트랜잭션 로그가 있는지 확인하십시오. 이러한 상황에서는 가져 오기 시간이 단축 될 수 있지만 메모리에 완전히 맞지 않을 수 있으므로 많은 시간이 필요합니다. 또한 단일 트랜잭션에서 4 천만 행을 가져 오려고하면 문제가 발생할 수 있습니다.

이 두 번째 경우의 실제 권장 사항 pt-archiver 와 같은 것을 사용 하는 것입니다. 방금 언급 한 것과 비슷한 작업을 수행하지만 트랜잭션 오버 헤드를 피하면서 "청크"로 수행됩니다 더 빠르지는 않지만 실패의 경우 전체 테이블을 롤백하지 않고 영원히 가져갑니다.) 언급 한 데이터 크기의 경우 이것이 가장 좋은 방법 일 것입니다.

마지막 옵션은 SELECT INTO OUTFILE / mysqldump 및 LOAD DATA / mysqlimport의 조합 으로 CSV (또는 TSV) 형식을 사용하여 내보내고 가져 오는 것입니다. 이것은 sql을 사용하여 더 큰 잠금을 생성했기 때문에 특정 이전 버전의 mysql에서 동시성이 필요한 경우 매우 일반적인 옵션이었습니다. mysqldump / import는 직렬화 된 방식으로 만 작동하므로 병렬화하는 옵션을 조사하여 큰 테이블에 매우 유용합니다.

어쨌든 여러 쿼리를 실행하는 경우 (개별적으로 실행, 구문 분석 및 최적화해야 함) 가장 중요한 병목 현상이 발생하므로 여러 SQL 문장을 피하십시오.


* MyISAM 구조는 빠른 방법으로 복사 할 수 없지만을 사용하여 임시로 디스크에 동기화하는 것은 매우 쉽습니다 FTWRL.


0

스키마에서 한 테이블에서 다른 테이블로 데이터를 이동하는 방법

create table your_table_name select * from old_schema_table;

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