엔터티에 변경 사항 저장:MySQL이 적절한 솔루션입니까?




database-design entity-attribute-value (6)

깊은 테스트에서 많은 것을 할 것을 조언하지만, 필자가 테스트 한 결과 INSERT와 SELECT를 사용하여 이전에 게시 한 테이블 정의로 매우 좋은 결과를 얻을 수있었습니다. 나는 더 깊은 결과를 얻는 지 누구든지 쉽게 반복하고 확인할 수 있도록 내 테스트를 자세히 설명 할 것이다. 테스트 전에 데이터를 백업하십시오.
나는 이것이 단지 테스트 일 뿐이며 실제 사례를 반영하거나 개선하지는 않지만 좋은 학습 방법이며 유용한 정보와 결과를 찾는 방법 일 것이라고 말해야합니다.

여기서 보았던 조언은 정말 좋으며, TEXT 대신 크기가 미리 정의 된 VARCHAR 형식을 사용하면 속도가 크게 향상됩니다. 그러나 속도는 빨라질 수 있습니다. 데이터 무결성을 위해 MyISAM을 사용하지 말 것을 권고합니다. InnoDB를 계속 사용하십시오.

검사 :

1. 설치 테이블 및 INSERT 데이터 2 억 :

CREATE TABLE `entity_versionable` (
  `version` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `fk_entity` INT(10) UNSIGNED NOT NULL,
  `str1` VARCHAR(255) DEFAULT NULL,
  `str2` VARCHAR(255) DEFAULT NULL,
  `bool1` TINYINT(1) DEFAULT NULL,
  `double1` DOUBLE DEFAULT NULL,
  `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`version`,`fk_entity`)
) ENGINE=INNODB AUTO_INCREMENT=230297534 DEFAULT CHARSET=latin1

테이블에 약 35 분 동안 2 억 2 천만 개의 행을 삽입하려면 peterm 이 테이블을 채우는 가장 좋은 방법 중 하나에 답변 한 내 다른 질문을 확인하십시오. 그것은 완벽하게 작동합니다.

무작위 데이터가없는 2 억 개의 행을 삽입하려면 다음 쿼리를 2 번 실행합니다 (무작위 데이터를 삽입 할 때마다 데이터 변경).

INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
SELECT 1, 'a1', 238, 2, 524627, '2013-06-16 14:42:25'
FROM
(
    SELECT a.N + b.N * 10 + c.N * 100 + d.N * 1000 + e.N * 10000 + f.N * 100000 + g.N * 1000000 + h.N * 10000000 + 1 N FROM 
     (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) d
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) e
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) f
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) g
    ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) h
) t;


* 실제 무작위 데이터가 2 억 개가있는 원본 테이블을 이미 가지고 있으므로 테이블 데이터와 스키마를 내보내고 동일한 스키마가있는 새로운 테스트 테이블로 가져와야합니다. 그렇게하면 실제 데이터로 새 테이블에서 테스트를 수행하고 개선 된 사항은 원래 테스트에도 적용됩니다.

2. 성능을 위해 새 테스트 테이블을 변경하십시오 (또는 1 단계에서 위의 예를 사용하여 더 나은 결과를 얻으십시오). 새로운 테스트 테이블 설정이 있고 임의의 데이터로 채워지면 위의 조언을 확인하고 테이블을 변경하여 속도를 높이십시오.

  • TEXT를 VARCHAR (255)로 변경하십시오.
  • 두 개 또는 세 개의 열이있는 양호한 기본 키 고유 인덱스를 선택하여 만듭니다. 첫 번째 테스트에서 버전 autoincrement 및 fk_entity로 테스트하십시오.
  • 필요한 경우 테이블을 분할하고 속도가 향상되는지 확인하십시오. 데이터 유형과 mysql 구성을 변경하여 실제 성능을 확인하기 위해 첫 번째 테스트에서이를 분할하지 말 것을 권합니다. 일부 파티션 및 개선 팁 은 다음 링크를 확인하십시오.
  • 테이블을 최적화하고 수리하십시오. 색인이 다시 만들어지고 검색 속도가 빨라집니다.

테이블 최적화 test . entity_versionable ;
수리 표 test . entity_versionable ;
* 최적화를 실행하고 색인을 최신 상태로 유지하고 매일 밤 실행하는 스크립트를 만드십시오.


3. 다음 스레드를주의 깊게 읽음으로써 MySQL 및 하드웨어 구성개선하십시오 . 그들은 읽을만한 가치가 있으며 더 나은 결과를 얻을 것이라고 확신합니다.

  • 쉽게 데이터베이스 하드 디스크 구성을 조금만 개선하십시오.
    돈 : 가능한 경우 기본 MySQL 데이터베이스에 SSD를 사용하고
    백업용으로 단독 형 기계식 하드 디스크. 다른 세 번째 하드 디스크에 MySQL 로그를 저장하도록 설정하여 속도 향상
    삽입. 몇 주 후에 기계적 하드 디스크의 조각 모음을 수행하십시오.
  • 성능 링크 : general&multiple-cores , configuration , IO 최적화 , Debiancores , 최상의 구성 , 48GB RAM 구성
  • SQL 쿼리 프로파일 링 : 쿼리를 프로파일 링하는 방법, 쿼리 에서 병목 현상이 발생할 수 있는지 확인 하는 방법
  • MySQL은 매우 메모리 집약적이며 가능한 경우 낮은 대기 시간의 CL7 DDR3 메모리를 사용합니다. 주제를 조금 벗어나지 만, 시스템 데이터가 중요한 경우 ECC 메모리를 찾아 볼 수도 있습니다.

4. 마지막으로, 테스트 테이블에서 INSERT 및 SEARCH를 테스트하십시오. 전 위의 테이블 스키마와 200,000,000 임의의 데이터로 내 테스트 내 테스트, 그것은 새로운 행을 INSERT에 0,001 초를 소비하고 1 억 개의 행을 검색하고 SELECT하는 데 약 2 분을 소비합니다. 그러나 그 유일한 테스트와 좋은 결과를 보인다 :)


5. 내 시스템 구성 :

  • 데이터베이스 : MySQL 5.6.10 InnoDB 데이터베이스 (테스트).
  • 프로세서 : AMD Phenom II 1090T X6 코어, 3910Mhz 각 코어.
  • RAM : 16GB DDR3 1600MHz CL8.
  • HD : SSD의 Windows 7 64 비트 SP1, SSD에 설치된 mySQL, 기계적 하드 디스크로 작성된 로그.
    아마도 가장 최근의 인텔 i5 또는 i7 중 하나가 4500MHz 이상으로 쉽게 오버 클럭 된 상태에서 더 나은 결과를 얻을 수 있습니다. MySQL은 하나의 SQL에 대해 하나의 코어 만 사용하기 때문입니다. 코어 속도가 높을수록 실행 속도가 빠릅니다.

6. MySQL에 대한 자세한 정보 :
오라일리 고성능 MySQL
MySQL 최적화 SQL 문


7. 다른 데이터베이스 사용하기 : MongoDB 나 Redis 는이 경우 완벽 할 것이며 MySQL보다 훨씬 빠를 것입니다. 둘 다 매우 배우기 쉽고 두 가지 모두 장점이 있습니다.
- MongoDB : MongoDB 로그 파일 증가

레디 스

나는 분명히 레디 스에게 갈 것입니다. Redis에서 로그를 저장하는 방법을 배우면 매우 빠른 속도로 로그를 관리하는 가장 좋은 방법입니다 : 로깅을위한 redis
Redis를 사용하는 경우 다음 조언을 염두에 두십시오.

  • Redis는 C로 컴파일되고 메모리에 저장되며 정보를 디스크에 자동 저장하는 몇 가지 다른 방법이 있습니다 (지속성). 걱정하지 않아도됩니다. (재난 시나리오의 경우 약 1 초의 로깅을 잃어 버리게됩니다).

  • Redis는 테라 바이트 규모의 데이터를 관리하는 많은 사이트에서 사용됩니다. 정보의 미친 양을 처리 할 수있는 방법이 많이 있으며 보안이 뛰어납니다 (stackoverflow, blizzard, twitter, youporn ..)

  • 로그가 매우 커질 것이므로 하드 디스크에 액세스하지 않고도 속도를 높이려면 메모리에 맞추어야합니다. 다른 날짜에 대해 다른 로그를 저장하고 일부만 메모리에 설정할 수 있습니다. 메모리 제한에 도달 한 경우 오류가 발생하지 않으며 모든 것이 완벽하게 작동하지만 자세한 내용은 Redis Faqs 를 확인하십시오.

  • Im은 Redis가 MySQL보다이 목적에 훨씬 더 빠를 것이라고 확신합니다. listssets 를 사용하여 데이터를 업데이트하고 데이터를 쿼리 / 검색하는 방법에 대해 알아야합니다. 정말로 진보 된 쿼리 검색이 필요할 경우, MongoDB와 함께 가야하지만, 간단한 날짜 검색의 경우에는 Redis에 완벽 할 것입니다.

Instagram 블로그의 Nice Redis 기사 .

내 "엔터티"테이블에서 수행하는 변경 내용을 저장하고 싶습니다. 로그와 같아야합니다. 현재 MySQL에서는이 테이블로 구현됩니다.

CREATE TABLE `entitychange` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `entity_id` int(10) unsigned NOT NULL,
  `entitytype` enum('STRING_1','STRING_2','SOMEBOOL','SOMEDOUBLE','SOMETIMESTAMP') NOT NULL DEFAULT 'STRING_1',
  `when` TIMESTAMP NOT NULL,
  `value` TEXT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
  • entity_id = 내 entity 테이블의 기본 키.
  • entitytype = entity 테이블에서 변경된 필드입니다. 때로는 하나의 필드 만 변경되며 때로는 여러 필드가 변경됩니다. 하나의 변화 = 한 행.
  • value = 필드의 "새 값"의 문자열 표현입니다.

예를 들어, entity.somedouble 필드를 3에서 2로 변경하면 다음 쿼리를 실행합니다.

UPDATE entity SET somedouble = 2 WHERE entity_id = 123;
INSERT INTO entitychange (entity_id,entitytype,value) VALUES (123,'SOMEDOUBLE',2);

지난 15 일 동안 특정 엔티티 및 엔티티 유형의 변경 사항을 select 해야합니다. 예 : 지난 15 일 동안 entity_id 123 대한 SOMEDOUBLE의 마지막 변경 사항.

자, 제가 싫어하는 두 가지가 있습니다 :

  1. 모든 데이터는 TEXT 로 저장됩니다. 대부분의 경우 (1 % 미만)는 실제로 텍스트가 아니지만, 대부분의 경우 DOUBLE 입니다. 이것이 큰 문제입니까?
  2. 테이블은 이미 2 억 개의 행을 가지고 있기 때문에 삽입 할 때 테이블은 정말로 느려집니다. 현재 내 서버로드는 최대 10-15입니다.

내 질문 : 두 가지 "병목 현상"을 어떻게 해결합니까? 나는 규모를 조정할 필요가있다.

내 접근 방식은 다음과 같습니다.

  1. 다음과 같이 저장하십시오 : http://sqlfiddle.com/#!2/df9d0 (찾아보기를 클릭하십시오) - entitychange 변경 테이블에 변경 사항을 저장하고 entitychange_[bool|timestamp|double|string] 데이터 유형에 따라 값을 저장하십시오. entitychange_[bool|timestamp|double|string]
  2. HASH(entity_id) 의한 파티셔닝 사용 - 저는 ~ 50 개의 파티션을 생각했습니다.
  3. 다른 데이터베이스 시스템을 사용해야합니까, 아마도 MongoDB입니까?

내가 언급 한 문제에 직면했다면 나는 다음과 같이 LOG 테이블을 디자인 할 것이다.

  1. EntityName : (문자열) 조작중인 엔터티 (필수)
  2. ObjectId : 기본 키가 조작되는 엔터티입니다.
  3. FieldName : (문자열) 엔터티 필드 이름입니다.
  4. OldValue : (String) 엔터티 필드의 이전 값입니다.
  5. NewValue : (String) Entity 필드의 새 값입니다.
  6. UserCode : 응용 프로그램 사용자 고유 식별자입니다. (필수)
  7. TransactionCode : 엔티티를 변경하는 모든 작업에는 고유 한 트랜잭션 코드 (예 : GUID)가 있어야합니다 (필수).
    여러 필드를 변경하는 엔티티에 대한 업데이트의 경우,이 열은 업데이트 (변환)의 모든 변경 사항을 추적하는 핵심 포인트가됩니다.
  8. ChangeDate : 거래 날짜. (필수)
  9. FieldType : TEXT 또는 Double과 같은 필드 유형을 나타내는 열거 또는 텍스트입니다. (필수)

이 방법을 사용하면
모든 엔티티 (표)를 추적 할 수 있음
보고서를 읽을 수 있습니다.
변경 사항 만 기록됩니다.
트랜잭션 코드는 단일 조치로 변경 사항을 탐지하는 핵심 포인트입니다.

BTW

Store the changes in the entitychange table and then store the value 
according to its datatype in entitychange_[bool|timestamp|double|string]

필요 없을 것입니다. 단일 테이블에 변경 사항과 데이터 유형이 있습니다.

Use partitioning by HASH(entity_id)

ChangeDate로 파티션을 나누거나 changeDate 용 백업 테이블을 생성하여 기본 LOG 테이블에서 백업하고 제거 할 수있을만큼 오래된 것을 선호합니다.

Should I use another database system, maybe MongoDB?

모든 데이터베이스는 자체적 인 문제와 단점이 있으므로 모든 RDBMS에서 디자인을 사용할 수 있습니다. MongoDB와 같은 문서 기반 데이터베이스의 유용한 비교는 여기에서 찾을 수 있습니다

희망이 도움이됩니다.


이를 임시 데이터베이스 (temporal database ) 라 부르며, 연구자들은 20 년 이상 임시 데이터를 저장하고 쿼리하는 가장 좋은 방법으로 고심하고 있습니다.

당신이하고있는 것처럼 EAV 데이터를 저장하려고하면 TEXT 열에 숫자 데이터를 저장하는 것이 많은 공간을 사용하고 테이블을 길게 늘리는 것이 비효율적입니다.

Sixth Normal Form이라고도하는 또 다른 옵션 (6NF에 대해 여러 개의 관련이없는 정의가 있지만)은 임시로 추적하려는 각 열에 대한 개정을 저장하는 추가 테이블을 저장하는 것입니다. 이것은 @ xtrm의 답이 제기하는 솔루션과 비슷하지만 변경되지 않은 열의 중복 사본을 저장할 필요가 없습니다. 그러나 그것은 테이블의 수가 폭발적으로 증가합니다.

앵커 모델링 에 대해 읽었습니다. 앵커 모델링 은 구조와 내용의 시간적 변화를 처리 할 것을 약속합니다. 하지만 아직 충분히 설명하지 못합니다. 나는 그것에 링크 만 할 것이고 아마도 당신에게 의미가있을 것입니다.

다음은 임시 데이터베이스에 대한 토론이 포함 된 두 권의 책입니다.


지금 나는 당신이 필요로하는 것이 무엇인지 이해하고 있다고 생각합니다. 기록이 변경된 버전 테이블입니다. 이는 동일한 결과를 얻을 수있는 또 다른 방법 일 수 있으며 현재 솔루션보다 우수한 성능을 제공하는지 확인하기 위해 빠른 테스트를 쉽게 할 수 있습니다. Symfony PHP Framework가 Versionable 플러그인으로 Doctrine에서 사용하는 방식입니다.
두 키, 버전 및 fk_entity의 기본 키 고유 색인이 있다는 것을 명심하십시오.
또한 저장된 값을 살펴보십시오. 변경되지 않은 필드 및 변경된 값의 변경된 값에 0 값을 저장합니다.

CREATE TABLE `entity_versionable` (
  `version` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `fk_entity` INT(10) UNSIGNED NOT NULL,
  `str1` VARCHAR(255),
  `str2` VARCHAR(255),
  `bool1` BOOLEAN,
  `double1` DOUBLE,
  `date` TIMESTAMP NOT NULL,
  PRIMARY KEY (`version`,`fk_entity`)
) ENGINE=INNODB DEFAULT CHARSET=latin1;


INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
VALUES ("1", "a1", "0", "0", "0", "2013-06-02 17:13:16");
INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
VALUES ("1", "a2", "0", "0", "0", "2013-06-11 17:13:12");
INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
VALUES ("1", "0", "b1", "0", "0", "2013-06-11 17:13:21");
INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
VALUES ("1", "0", "b2", "0", "0", "2013-06-11 17:13:42");
INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
VALUES ("1", "0", "0", "1", "0", "2013-06-16 17:19:31");

/*Another example*/
INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
VALUES ("1", "a1", "b1", "0", "0", CURRENT_TIMESTAMP);


SELECT * FROM `entity_versionable` t WHERE 
(
    (t.`fk_entity`="1") AND 
    (t.`date` >= (CURDATE() - INTERVAL 15 DAY))
);


성능 향상을위한 또 다른 단계는 아마도 한 달에 한 번씩 별도의 테이블에 모든 내역 로그 레코드를 저장할 수 있습니다. 그렇게하면 각 테이블에 많은 레코드가 생기지 않을 것이고 날짜별로 검색하는 것이 정말 빠를 것입니다.


TEXT 열에 정수를 저장하는 것은 아무 TEXT 아닙니다! TEXT 는 가장 비싼 유형입니다.

나는 감시하고자하는 필드 당 하나의 로그 테이블을 만드는 것으로 갈 것입니다.

CREATE TABLE entitychange_somestring (
    entity_id INT NOT NULL PRIMARY KEY,
    ts TIMESTAMP NOT NULL,
    newvalue VARCHAR(50) NOT NULL, -- same type as entity.somestring
    KEY(entity_id, ts)
) ENGINE=MyISAM;

실제로 그들을 분할하십시오.

MyISAM 엔진을 사용하는 것이 좋습니다. 이러한 (제한되지 않은) 삽입 전용 테이블에 대한 트랜잭션은 필요하지 않습니다.


INSERT가 왜 그렇게 느리며, 더 빨리 만들 수 있습니까?

이것들은 제가 보게 될 것들입니다 (그리고 대략 거치게됩니다).

  1. 새로운 AUTO_INCREMENT-id를 생성하고이를 기본 키에 삽입하는 것은 잠금을 필요로합니다 (InnoDB에는 특별한 AUTO-INC 잠금이 있습니다. 이것은 문이 끝날 때까지 유지되어 시나리오에서 테이블 잠금 역할을합니다). 이것은 상대적으로 빠른 작업이므로 일반적으로 문제는 아니지만 다른 한편으로는 (유닉스)로드 값이 10에서 15까지라면 잠금을 해제 할 때까지 대기하는 프로세스가있을 수 있습니다. 내가 제공 한 정보에서 대리 키 'id'를 사용하지 않습니다. 해당 열을 삭제하면 성능이 크게 변경되는지 확인하십시오. (BTW, 테이블에 기본 키가 필요하다는 규칙은 없습니다. 갖고 있지 않으면 괜찮습니다)

  2. InnoDB는 INSERT에 비교적 비싸다. 이는 거래와 같은 추가 기능을 허용하기 위해 수행되는 거래이며 귀하에게 영향을 줄 수도 있고 아닐 수도 있습니다. 모든 당신의 행동이 원자력이기 때문에, 나는 거래 할 필요가 없다. 즉, MyISAM을 사용해보십시오. 참고 : MyISAM은 대개 테이블 잠금과 레코드 잠금 만 지원하기 때문에 대용량 테이블에는 적합하지 않지만 병행 삽입을 지원하므로 선택이 가능합니다 (특히 기본 키를 삭제할 경우 위 참조)

  3. 데이터베이스 스토리지 엔진 매개 변수로 재생할 수 있습니다. InnoDB와 MyISAM 모두 당신이 변경할 수있는 옵션이 있습니다. 그 중 일부는 TEXT 데이터가 실제로 저장되는 방식에 영향을 미치고 다른 일부는 더 광범위한 기능을합니다. 특별히 살펴 봐야 할 것은 innodb_flush_log_at_trx_commit 입니다.

  4. TEXT 열은 NULL이 아닌 값이있는 경우에만 상대적으로 비쌉니다. 현재 모든 TEXT 열에 값을 저장 하고 있습니다. 다음과 같은 시도를해볼 가치가 있습니다. value_intvalue_double 필드를 테이블에 추가하고 해당 값을 해당 열에 저장합니다. 예, 약간의 공간을 낭비하지만 더 빠를 수도 있습니다. 그러나 이는 데이터베이스 저장 엔진과 설정에 크게 좌우됩니다. TEXT 열 성능에 대해 사람들이 생각하는 많은 내용이 사실이 아닙니다. ( VARCHAR vs TEXT 관련 질문에 대한 내 대답을 참조하십시오)

  5. 정보를 두 개 이상의 테이블에 분산시킬 것을 제안했습니다. 테이블이 서로 완전히 독립적 인 경우에만 좋은 아이디어입니다. 그렇지 않으면 어떤 변화에 대해서도 둘 이상의 INSERT 작업이 끝나게 될 것이므로 훨씬 더 악화 될 가능성이 높습니다. 일반적으로 데이터를 정규화하는 것이 좋지만 (tm), 여기서 성능을 손상시킬 수 있습니다.

SELECT를 빠르게 실행하려면 무엇을 할 수 있습니까?

  1. 적절한 키. 그리고 적절한 열쇠. 그리고 적절한 경우에 대비하여 적절한 키를 언급하는 것을 잊어 버렸습니다. 선택한 내용이 무엇인지 자세히 설명하지는 않지만 "SELECT * FROM entitychange WHERE entity_id = 123 AND ts> ..."와 유사하다고 가정합니다. entity_id 및 ts의 단일 복합 색인은이 작업을 빠르게 수행 할 수 있어야합니다. INSERT마다 인덱스를 업데이트해야하기 때문에 entity_id, tsts, entity_id 의 성능을 시험해 볼 가치가 있습니다. 차이가있을 수 있습니다.

  2. 파티셔닝. 나는 당신이 당신의 질문에서 질문하지 않은 경우에이 주제를 제기하지 않을 것입니다. 왜 테이블을 분할하고 싶은지는 말하지 않습니다. 성능 측면에서 보면 적절한 키가 있으면 일반적으로 차이가 없습니다. 성능을 향상시킬 수있는 몇 가지 구체적인 설정이 있지만 이와 함께 진행하려면 적절한 하드웨어 설정이 필요합니다. 테이블을 분할하기로 결정했다면, entity_id 또는 TIMESTAMP 컬럼으로 테이블을 분할하는 것을 고려하십시오. 타임 스탬프를 사용하면 오래된 데이터를 보관 드라이브에 보관하는 보관 시스템을 구축 할 수 있습니다. 그러나 그러한 분할 시스템은 약간의 유지 보수 (시간이 지남에 따라 분할 영역 추가)가 필요합니다.

원시 삽입 속도에 대한 쿼리 성능에 대해 걱정하지 않으셔서 SELECT 성능에 대해 자세히 설명하지 않겠습니다. 관심이 있으시면 자세한 내용을 제공해주십시오.





temporal-database