14.6.7 InnoDB 테이블에서의 제한
mysql
데이터베이스의 MySQL 시스템 테이블을 MyISAM
에서 InnoDB
테이블로 변환하지 마십시오. 이것은 지원되지 않는 작업입니다. 이렇게하면, mysql_install_db 프로그램을 사용하여 백업에서 이전 시스템 테이블을 복원하거나 다시 생성 될 때까지 MySQL은 다시 시작되지 않습니다.
NFS 볼륨에서 데이터 파일과 로그 파일이 사용되도록 InnoDB
를 구성하는 것은 적절하지 않습니다. 그렇지 않으면 파일이 다른 프로세스에 의해 잠겨 MySQL에서 사용할 수 없게 될 가능성이 있습니다.
최대와 최소
테이블에는 최대 1017 개의 컬럼을 포함 할 수 있습니다 (MySQL 5.6.9에서 이전의 1000 개 제한에서 상승되었습니다).
테이블에는 최대 64 개의 보조 인덱스 를 포함 할 수 있습니다.
기본적으로 단일 컬럼 인덱스의 인덱스 키를 최대 767 바이트 수 있습니다. 인덱스 키 프리픽스도 같은 길이 제한이 적용됩니다. 섹션 13.1.13 "CREATE INDEX 구문" 을 참조하십시오. 예를 들어, UTF-8 문자 세트와 캐릭터 당 최대 3 바이트를 사용한다고 가정하면,
TEXT
또는VARCHAR
컬럼에서 255 자보다 긴 컬럼 프리픽스 인덱스를 사용하면이 제한에 도달 할 수 있습니다.innodb_large_prefix
구성 옵션을 사용하면DYNAMIC
및COMPRESSED
행 형식을 사용하는InnoDB
테이블에서이 길이 제한이 3072 바이트로 증가합니다.허용되는 최대 값보다 큰 인덱스 프리픽스 길이를 사용하려고하면 오류가 생성됩니다. 슬레이브에서도
innodb_large_prefix
옵션을 설정할 수 없습니다이 제한의 영향을받을 수있는 고유 인덱스를 슬레이브가있는 경우는 복제 구성에서 이러한 오류를 방지하기 위해이 옵션을 마스터 로 설정하는 것을 피하십시오.InnoDB
의 내부 최대 키 길이는 3500 바이트이지만, MySQL 자체는 3072 바이트로 제한되어 있습니다. 이 제한은 다중 컬럼 인덱스의 결합 된 인덱스 키의 길이에 적용됩니다.MySQL 인스턴스를 만들 때
innodb_page_size
옵션을 지정하여InnoDB
의 페이지 크기 를 8K 바이트 또는 4K 바이트까지 줄이면 16K 바이트의 페이지 크기에 해당하는 3072 바이트 제한에 따라 비례 적으로 인덱스 키의 최대 길이 도 짧아집니다. 즉, 인덱스 키의 최대 길이는 페이지 크기가 8K 바이트의 경우 1536 바이트 페이지 크기가 4K 바이트의 경우 768 바이트입니다.가변 길이 컬럼 (
VARBINARY
,VARCHAR
,BLOB
및TEXT
)을 제외하고 행의 최대 길이는 데이터베이스 페이지의 절반보다 조금 짧아집니다. 즉, 기본 페이지 크기 16K 바이트에서 최대 행 길이가 8000 바이트입니다. MySQL 인스턴스를 만들 때innodb_page_size
옵션을 지정하여 페이지 크기를 줄이면 행의 최대 길이는 8K 바이트의 페이지는 4000 바이트 4K 바이트의 페이지는 2000 바이트입니다.LONGBLOB
및LONGTEXT
컬럼은 4G 바이트 미만이어야,BLOB
및TEXT
컬럼을 포함하는 행 전체 길이는 4G 바이트 미만이어야합니다.줄의 길이가 한 페이지의 절반보다 짧은 경우는 행 전체가 그 페이지 내에 로컬로 저장됩니다. 섹션 14.10.2 "파일 공간 관리" 에서 설명한 바와 같이, 반 페이지 이상 행은 행이 반 페이지 내에 맞게 가변 길이 컬럼이 외부 오프 페이지 저장 용으로 선택됩니다.
InnoDB
는 내부적으로 65,535 바이트 이상의 행 크기가 지원되고 있습니다 만, MySQL 자체는 모든 컬럼을 결합한 크기에 65,535 행의 크기 제한이 부과됩니다.mysql>
CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000),
->c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
->f VARCHAR(10000), g VARCHAR(10000)) ENGINE=InnoDB;
ERROR 1118 (42000) : Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535 You have to change some columns to TEXT or BLOBs섹션 D.10.4 "테이블 컬럼 및 행 크기 제한" 을 참조하십시오.
일부 오래된 운영 체제에서는 파일은 2G 바이트보다 작해야합니다. 이것은
InnoDB
자체의 제한은 없습니다. 그러나 큰 테이블 공간이 필요한 경우는 하나가 아닌 여러 개의 작은 데이터 파일을 사용하여 구성하거나 더 큰 데이터 파일을 작성해야합니다.InnoDB
로그 파일을 결합한 크기는 최대 512G 바이트까지 할 수 있습니다.테이블 스페이스의 최소 크기는 10M 바이트 조금 넘는 크기입니다. 테이블 스페이스의 최대 크기는 40 억 데이터베이스 페이지 (64T 바이트)입니다. 이것은 테이블의 최대 크기이기도합니다.
InnoDB
의 기본 데이터베이스 페이지 크기는 16K 바이트이지만, MySQL 인스턴스를 만들 때innodb_page_size
옵션을 지정하면 페이지 크기를 8K 바이트 또는 4K 바이트까지 줄일 수 있습니다.참고페이지 크기를 크게하는 것은 지원되는 작업은 없습니다.
InnoDB
는 16K 바이트를 초과하는 페이지 크기는 일반적으로 동작이 보장되지 않습니다. InnoDB를 컴파일하거나 실행할 때 문제가 발생할 수 있습니다. 특히 Barracuda 파일 형식의ROW_FORMAT=COMPRESSED
에서는 페이지 크기가 16K 바이트에서 14 비트 포인터를 사용하는 것이 전제가되고 있습니다.특정
InnoDB
페이지 크기를 사용하는 MySQL 인스턴스는 다른 페이지 크기를 사용하는 인스턴스 데이터 파일과 로그 파일을 사용할 수 없습니다. 이 제한은 16K 바이트 이외의 페이지 크기가 지원되는 MySQL 5.6의 데이터를 사용하여 복원 또는 다운 그레이드 작업이 영향을받을 수 있습니다.
인덱스 유형
MySQL 5.6.4 이후에서는,
InnoDB
테이블에서FULLTEXT
인덱스를 지원하고 있습니다. 자세한 내용은 섹션 14.2.13.3 "FULLTEXT 인덱스" 를 참조하십시오.InnoDB
테이블에서는 공간 데이터 형식이 지원되지만 그 인덱스는 지원되지 않습니다.
InnoDB 테이블상의 제약
각 인덱스 트리를 랜덤 다이빙 을하고 그에 따라 인덱스 카디 낼 리티 견적을 업데이트하면 (
SHOW INDEX
출력「Cardinality」
열에 표시되도록)ANALYZE TABLE
인덱스 중요도가 결정됩니다. 이들은 단지 견적이기 때문에ANALYZE TABLE
을 반복하면 다른 숫자가 생성 될 수 있습니다. 이에 따라ANALYZE TABLE
의InnoDB
테이블에서의 속도는 빨라지지만 모든 행이 고려되는 것은 아니기 때문에 100 % 정확하다고는 말할 수 없습니다.섹션 14.13.16.1 "영구 옵티 마이저 통계 매개 변수 구성" 에 설명 된 바와 같이,
innodb_stats_persistent
구성 옵션을 선택하면ANALYZE TABLE
에서 수집 된 통계 의 정확성 및 안정성을 향상시킬 수 있습니다. 통계는 정기적으로 다시 계산되지 않기 때문에이 설정을 사용하면 기존과 마찬가지로 인덱스 된 컬럼 데이터의 주요 변경 후 (서버 재부팅 후 등)에ANALYZE TABLE
을 수행 할 수 중요합니다.innodb_stats_persistent_sample_pages
시스템 변수 (영구 통계 설정이 켜져있는 경우) 또는innodb_stats_transient_sample_pages
시스템 변수 (영구 통계 설정이 꺼져있는 경우)를 변경하면 랜덤 다이브의 수를 변경할 수 있습니다.MySQL에서는 조인의 최적화시에만 인덱스 카디 낼 리티 견적이 사용됩니다. 일부 결합이 제대로 최적화되지 않는 경우는
ANALYZE TABLE
을 사용하여보십시오.ANALYZE TABLE
에서는 특정 테이블에 충분한 값이 생성되지 않을 경우 특정 인덱스의 사용을 강제하는 쿼리와 함께FORCE INDEX
를 사용하거나 MySQL에서 테이블 스캔보다 인덱스 검색이 우선되도록max_seeks_for_key
시스템 변수를 설정하십시오. 섹션 5.1 "서버 시스템 변수" 및 섹션 B.5.6 "최적화 관련 문제" 를 참조하십시오.테이블에서 문 또는 트랜잭션이 실행되고 있고,
ANALYZE TABLE
다음에 같은 테이블에서 두 번째ANALYZE TABLE
작업이 수행되면 그 문 또는 트랜잭션이 완료 될 때까지 두 번째ANALYZE TABLE
조작은 블록 됩니다. 이 동작이 발생하는 원인은ANALYZE TABLE
의 실행이 완료되면ANALYZE TABLE
에 의해 현재로드중인 테이블 정의에 사용되지 않는 것으로 표시되기 때문입니다. 새로운 문이나 트랜잭션 (두 번째ANALYZE TABLE
문을 포함)은 새로운 테이블 정의를 테이블 캐시에로드해야합니다. 이 동작은 현재 실행중인 명령문이나 트랜잭션이 완료 이전 테이블 정의가 제거 될 때까지 발생 될 수 없습니다. 여러 병렬 테이블 정의를로드하는 것은 지원되지 않습니다.SHOW TABLE STATUS
는 테이블에서 예약 된 실제 크기를 제외하고,InnoDB
테이블에 대한 정확한 통계를 얻을 수 없습니다. 행 카운트는 단순히 SQL 최적화에 사용되는 어림셈입니다.병렬 트랜잭션에서 동시에 다양한 수의 행이 "참조"될 가능성이 있기 때문에
InnoDB
테이블은 행의 내부 카운트가 유지되지 않습니다.SELECT COUNT(*) FROM t
명령문을 처리하기 위해InnoDB
는 테이블 인덱스를 검색되지만 인덱스가 완전히 버퍼 풀에없는 경우에는 다소 시간이 걸립니다. 테이블이 자주 변경되지 않는 경우는 MySQL 쿼리 캐시를 사용하는 것이 적절한 해결책입니다. 빠르게 계산하려면 스스로 만든 카운터 테이블을 사용하여 실행되는 삽입 및 삭제에 따라 응용 프로그램에서 업데이트 할 수 있도록해야합니다. 대략적인 행 카운트가 충분하지 않은 경우,SHOW TABLE STATUS
를 사용할 수 있습니다. 섹션 8.5 "InnoDB 테이블 최적화" 를 참조하십시오.Windows에서
InnoDB
는 항상 데이터베이스 및 테이블 이름을 내부적으로 소문자로 저장됩니다. 바이너리 형식의 데이터베이스를 Unix에서 Windows로 또는 Windows에서 Unix로 이동하려면 모든 데이터베이스 및 테이블을 소문자 이름을 사용하여 만듭니다.최대 열 값을 얻기 위해 테이블에서 인덱스 된
SELECT MAX(
검색과 동일한 작업을 수행 할 수 있도록ai_col
)AUTO_INCREMENT
컬럼ai_col
을 인덱스의 일부로 정의해야합니다. 일반적으로 이것은 열을 어느 테이블 인덱스의 첫 번째 컬럼함으로써 실현됩니다.InnoDB
는 테이블에 사전에 지정된AUTO_INCREMENT
컬럼의 초기화 동안AUTO_INCREMENT
컬럼과 연관된 인덱스의 마지막에 배타적 잠금을 설정합니다. 자동 증가 카운터에 액세스 할 때InnoDB
는 전체 트랜잭션의 끝까지가 아니라 현재의 SQL 문이 끝날 때까지 존속하는 특별한AUTO-INC
테이블 잠금 모드가 사용됩니다.AUTO-INC
테이블 잠금이 유지되는 동안 다른 클라이언트는 테이블에 삽입 할 수 없습니다. 섹션 14.6.5 "InnoDB에서 AUTO_INCREMENT 처리" 를 참조하십시오.MySQL 서버를 다시 시작하면
AUTO_INCREMENT
컬럼에 대해 생성되었지만 한번도 포함되지 않았던 이전 값 (즉, 롤백 된 오래된 트랜잭션에서 생성 된 값)이InnoDB
에서 재사용 될 수 있습니다 .AUTO_INCREMENT
정수 컬럼의 값이 부족하고 후속INSERT
작업에서 중복 키 오류가 반환됩니다. 이것은 일반적인 MySQL 동작이며,MyISAM
의 동작과 비슷합니다.DELETE FROM
는 테이블을 다시 생성하지 않지만, 그 대신 모든 행을 하나씩 삭제합니다.tbl_name
현재 계단식 된 외부 키의 액션에서는 트리거가 활성화되어 있지 않습니다.
내부 InnoDB 컬럼 (
DB_ROW_ID
,DB_TRX_ID
,DB_ROLL_PTR
,DB_MIX_ID
등)의 이름과 일치하는 컬럼 이름을 가진 테이블을 만들 수 없습니다. 서버는 오류 1005를보고하고 오류 메시지의 오류 -1을 참조하십시오. 이 제약은 대문자 이름을 사용하는 경우에만 적용됩니다.
잠금과 트랜잭션
innodb_table_locks=1
(디폴트)의 경우,LOCK TABLES
에서 각 테이블에 2 개의 잠금을 획득합니다. MySQL 레이어에서 테이블 잠금 외에도,InnoDB
테이블 잠금도 얻을 수 있습니다. 버전 4.1.2 이전의 MySQL에서는InnoDB
테이블 잠금을 획득하지 못했습니다. 이 이전 동작은innodb_table_locks=0
을 설정하면 선택할 수 있습니다.InnoDB
테이블 잠금이되지 않는 경우에는 테이블의 일부 레코드를 다른 트랜잭션에 의해 잠겨없이LOCK TABLES
을 완료합니다.MySQL 5.6에서는
LOCK TABLES ... WRITE
를 사용하여 명시 적으로 잠긴 테이블에는innodb_table_locks=0
이 잘못되었습니다.LOCK TABLES ... WRITE
암시 적으로 (예를 들어, 트리거를 사용하여) 또는LOCK TABLES ... READ
하여 읽기 또는 쓰기에 잠긴 테이블은 유효합니다.트랜잭션에서 보유하고있는 모든
InnoDB
잠금은 트랜잭션이 커밋되거나 중단되면 해제됩니다. 따라서autocommit=1
모드의InnoDB
테이블에서LOCK TABLES
를 호출해도, 취득 된InnoDB
테이블 잠금은 즉시 해제되어 버리기 때문에 전혀 의미가 없습니다.LOCK TABLES
는 암시 적COMMIT
및UNLOCK TABLES
실행되므로 트랜잭션이 실행되는 동안 추가 테이블을 잠글 수 없습니다.병렬 데이터 변경 트랜잭션의 1023 개의 제한은 MySQL 5.5 이상으로 상승되었습니다. 현재 그 제한은 Undo 레코드가 생성되는 128 * 1023 개의 병렬 트랜잭션되었습니다. 적절한 거래 구조를 변경해야하는 해결 방법 (더 자주 커밋 등)을 모두 해제 할 수 있습니다.