MySQL에서 MEMORY 스토리지 엔진을 사용해야하는 이유는 무엇입니까?


28

나는 최근에 MySQL에 내가 알지 못하는 "메모리"엔진이 있다는 것을 발견했다. 이 옵션을 사용하면 성능이 크게 향상되는 것처럼 보이므로 이에 따른 단점이 있는지 궁금합니다. 내가 아는 두 가지는 다음과 같습니다.

  1. 문제의 테이블을 보유하기에 충분한 RAM이 필요합니다.
  2. 기계가 종료되면 테이블이 유실됩니다.

AWS EC2를 사용하고 있기 때문에 # 1은 문제가되지 않아야하며 필요한 경우 더 많은 메모리가있는 인스턴스 유형으로 이동할 수 있습니다. 필요에 따라 디스크로 다시 덤프하여 # 2를 완화 할 수 있다고 생각합니다.

다른 어떤 문제가 있습니까? 메모리 엔진이 MyISAM 또는 InnoDB보다 성능을 떨어 뜨릴 수 있습니까? 이 엔진과는 다른 인덱스를 읽은 것 같습니다. 이것이 내가 걱정해야 할 것입니까?

답변:


27

http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html 의 기능 가용성 목록을 보면 두 가지 가능한 문제가 발생합니다.

  1. 트랜잭션 또는 FK 지원이 없으므로 자체 코드에서 트랜잭션 무결성 및 참조 무결성을 관리해야 함을 의미합니다. 이는 DB가이를 수행하도록하는 것보다 훨씬 덜 효율적일 수 있습니다. 예상되는 행동 패턴).
  2. 테이블 수준 잠금 만 해당 : 앱에 동일한 테이블 집합에 대해 여러 개의 동시 작성기가 필요한 경우 또는 읽기 작업에서 잠금을 사용하여 일관된 데이터를 읽을 수있는 경우 (예 : 디스크 기반 테이블) 확장성에 심각한 장애가 될 수 있습니다. 훨씬 더 미세한 잠금을 지원합니다. 충분한 내용이 현재 RAM에 캐시되어 있으면 훨씬 더 나은 성능을 발휘합니다.

그 외에도 RAM이 충분하다고 가정하면 메모리 기반 테이블이 디스크 기반 테이블보다 빠릅니다. 서버 인스턴스가 재설정 될 때 발생하는 문제를 해결하기 위해 디스크에 스냅 샷을 찍는 것을 고려해야합니다. 데이터를 자주 캡처해야하는 경우 전체적인 성능 이점을 완전히 무시할 수 있습니다. 그러한 인스턴스의 데이터는 하루에 한 번만 백업 할 수 있지만 대부분의 경우 허용되지 않습니다.

대안은 다음과 같습니다.

  1. 디스크 기반 테이블을 사용하되, 주어진 시간에 모든 RAM을 RAM에 담을 수있는 충분한 RAM이 있는지 확인하십시오 (그리고 충분한 RAM이 시스템, OS의 다른 프로세스를 설명하는 데 필요한 것보다 많을 수 있음) IO 버퍼 / 캐시 등)
  2. 각 시작시 테이블의 전체 내용 (모든 데이터 및 색인 페이지)을 스캔하여 SELECT * FROM <table> ORDER BY <pkey fields>각 테이블 SELECT <indexed fields> FROM <table> ORDER BY <index fields>및 각 색인 에 대해 내용을 메모리에 사전로드하십시오.

이렇게하면 모든 데이터가 RAM에 저장되므로 쓰기 작업의 I / O 성능 만 걱정하면됩니다. 앱의 공통 작업 세트가 전체 DB보다 훨씬 작을 경우 (대부분의 경우 대부분의 애플리케이션에서 대부분의 사용자는 가장 최신 데이터 만 볼 수 있음) 얼마나 많은 양을 선택하는 것이 더 나을지 메모리에 미리로드하기 위해 스캔하여 나머지는 디스크에서로드 할 수 있습니다.


인 메모리 데이터베이스에 트랜잭션 무결성이 필요한 이유는 무엇입니까? 전원이 꺼지면 어쨌든 모든 것이 손실됩니다.
osa

@osa : 모든 것을 직렬화하는 것이 아니라 동시 액세스를 허용한다고 가정하면,이를 위해 어떤 형태의 무결성 관리를 원할 것입니다.
David Spillett

14

메모리 스토리지 엔진을 사용하지 않는 경우와 InnoDB가 더 빠른 경우가 많이 있습니다. 간단한 단일 스레드 테스트가 아니라 동시성에 대해서만 생각하면됩니다.

충분한 버퍼 풀이있는 경우 InnoDB는 읽기 작업을위한 메모리 상주가됩니다. 데이터베이스 에는 캐시가 있습니다. 그들은 몸을 따뜻하게한다!

또한 행 수준 잠금 및 MVCC 의 값을 과소 평가하지 마십시오 (판독기는 작성자를 차단하지 않음). 쓰기가 디스크에 지속될 때 "느린"것일 수 있습니다. 그러나 최소한 메모리 테이블 (MVCC 없음; 테이블 레벨 잠금)에있는 것처럼 쓰기 작업 중에는 차단되지 않습니다.


3

기록을 위해. 일부 정보를 저장하기 위해 메모리에서 Mysql 테이블을 테스트했습니다. 그리고 동일한 정보를 저장하기 위해 PHP의 APCu를 테스트했습니다.

58000 레지스트리. (varchar + 정수 + 날짜).

  1. 원본 정보 24MB 텍스트 형식 (csv 형식)
  2. PHP의 APC는 44.7mb의 RAM을 사용합니다.
  3. MySQL의 테이블은 575mb의 RAM을 사용합니다.

테이블에는 단일 인덱스 만 있으므로 주요 요소라고 생각하지 않습니다.

결론:

메모리 테이블은 너무 큰 메모리를 사용하므로 "큰"테이블에 대한 옵션아닙니다 .


2
이것은 지나치게 단순화 된 답변입니다. 더 작은 데이터 유형을 사용하고 BTREE를 인덱스 유형으로 명시 적으로 정의하고 RAM에로드되는 데이터의 양을 제한하여 MEMORY 스토리지 엔진을 조정할 수 있습니다. 더 작은 세트에는 여전히 실행 가능한 옵션입니다. 공격적인 디스크 I / O와 같은 다른 요소도 있습니다. 내 게시물 참조 dba.stackexchange.com/questions/6156/…dba.stackexchange.com/questions/2868/… )
RolandoMySQLDBA

사실, 나는 인덱스 변경 (그리고 심지어 완전히 삭제하는)을 확인했으며 크기가 크게 변경되지 않았습니다 (테이블을 처음부터 재구성하는 것을 포함하여). IMHO Mysql은 후드 아래에서 무언가를하고 있으며 일종의 최적화 또는 열 당 가장 큰 크기 (예 : varchar)를 할당 할 수 있습니다.
magallanes 2018 년

6
그 이유는 거의 확실하게 VARCHAR 때문입니다. "MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length." dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html 사실상 MEMORY 엔진에서는 VARCHAR이 CHAR이됩니다.
Matthew1471

2

MEMORY 기반 테이블의 다른 단점은 동일한 쿼리에서 여러 번 참조 할 수 없다는 것입니다. 적어도 그 행동은 v5.4까지 발견되었습니다. CTE (v8.x부터)를 사용하는 방법 복잡한 절차에 mem 기반 중간 테이블을 사용할 필요가 없습니다.


1

MySQL 및 MariaDB 매뉴얼에 따르면 BLOB 및 CLOB (다양한 TEXT 유형)는 MEMORY 스토리지에서 지원되지 않습니다. 우리 자신의 목적을 위해 MEMORY 스토리지 엔진을 거의 쓸모 없게 만들었습니다.

http://dev.mysql.com/doc/refman/5.7/en/memory-storage-engine.html

MEMORY 테이블은 BLOB 또는 TEXT 열을 포함 할 수 없습니다.

https://mariadb.com/kb/en/mariadb/memory-storage-engine/

VARCHAR과 같은 가변 길이 유형은 MEMORY 테이블에서 사용할 수 있습니다. MEMORY 테이블에는 BLOB 또는 TEXT 열이 지원되지 않습니다.

데이터베이스의 일부만 MEMORY 스토리지로 변환하려고 시도 할 때 스토리지 간 엔진 외부 키가 지원되지 않는 것으로 나타났습니다. 따라서 BLOB / CLOB를 포함하는 테이블에 대한 외래 키 참조를 가져야하는 모든 테이블은 비 메모리 스토리지 유형이어야합니다 (적어도 InnoDB 자식 테이블에 영향을 미침).


1

MEMORY 테이블은 영구 스토리지, 특히 대규모 데이터 서브 세트 또는 보존이 중요한 모든 용도로 사용되지 않습니다. 내 경험에서 가장 좋은 목적은 복잡한 절차 중에 임시 테이블을 만들고 수집하는 동안 일시적인 레코드를 저장하는 것입니다. 엔진의 키 버퍼 임계 값이 발생하지 않을 정도로 높게 설정되어 있으면이 목적을 위해 대부분의 다른 테이블 유형보다 훨씬 빠르게 수행됩니다. 디스크 쓰기 디스크 I / O가 없기 때문에 MyISAM 또는 InnoDB보다 10 배 빠른 속도로 작동 할 수 있으며 특정 프로 시저 내에 캡슐화 된 테이블의 경우 인덱싱 및 관계가 그다지 중요하지 않습니다. 지속성이 예상되는 곳.


1

이전 답변 외에도. MySQL 5.7 매뉴얼에서 직접 :

"메모리 성능은 업데이트 처리시 단일 스레드 실행 및 테이블 잠금 오버 헤드로 인한 경합으로 인해 제한됩니다. 이는 특히 쓰기를 포함하는 명령문 믹스의 경우로드가 증가 할 때 확장 성을 제한합니다."

... 이것은 매우 실제적인 한계입니다. 예를 들어, 멋진 빠른 MEMORY 임시 테이블을 만들려고 여러 세션이있는 경우 단일 스레딩으로 인해 성능 병목 현상이 발생할 수 있습니다.

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