DynamoDB/Aurora: 드문드문 색인 및 부분 색인

a에서 저는 Amazon DynamoDB 용어에 대한 어휘표를 구축하려고 했습니다. 이 용어들은 관계 데이터베이스 용어처럼 보이지만 서로 다른 기술적 의미를 가지고 있습니다.여기에 그것에 대한 더 많은 정보가 있다.AWS 데이터베이스를 사용하고 DynamoDB와 Aurora 또는 다른 RDS 데이터베이스를 자주 전환하면 서로 다른 의미의 같은 용어에 사용될 수 있습니다.
인덱스는 조회표의 일부분에 더 빠르고 질서정연한 접근을 제공하기 위해 데이터베이스에서 유지보수하는 불필요한 구조이다.기본적으로, 테이블이나 구역을 스캔해서 모든 값을 읽고 필터를 할 필요가 없고, 그 중의 일부분에 접근할 수 있으며, 너무 많은 필터를 하지 않고 정렬할 수 있습니다.이 작은 부분은 행과 열 또는 항목 및 속성의 하위 집합입니다.
Aurora와 PostgreSQL 호환을 예로 들어 관계 데이터베이스 어휘표의 덮어쓰기 인덱스와 부분 인덱스가 무엇인지 설명합니다.

postgres=> \c postgres://reader:[email protected]:5432/pfmegrnargs

pfmegrnargs=> \! rm /var/tmp/rna.csv
pfmegrnargs=> \copy rna to '/var/tmp/rna.csv' csv header
COPY

pfmegrnargs=> \! du -h /var/tmp/rna.csv
24G     /var/tmp/rna.csv
RNA 테이블을 로컬 csv에서 약 25GB로 다운로드했습니다.

postgres=> \c postgres://postgres:postgres@database-1.cluster-cvlvfe1jv6n5.eu-west-1.rds.amazonaws.com:5432/postgres
You are now connected to database "postgres" as user "postgres".
PostgreSQL과 호환되는 RDS Aurora (소형db.r6g.large 2 cVPU 16GB RAM) 를 만들었습니다.

postgres=> CREATE TABLE rna (id int8 null, upi varchar(30) not null, "timestamp" timestamp null, userstamp varchar(60) null, crc64 bpchar(16) null, len int4 null, seq_short varchar(4000) null, seq_long text null, md5 varchar(64) null, constraint rna_pkey primary key (upi));
CREATE TABLE
이것은 원본과 같은 표이지만, 메인 키를 제외하고는 아무런 인덱스도 없습니다

postgres=> \copy rna from '/var/tmp/rna.csv' csv header
COPY
postgres=> vacuum rna;
VACUUM
이것은 CSV에서 3500만 줄을 불러왔다.
나는 올해의 최신 데이터 줄을 조회할 것이다.

postgres=> explain (analyze,verbose,buffers) select upi from rna where timestamp > date '2021-01-01';

                                                                 QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
 Gather  (cost=1000.00..3179976.11 rows=254424 width=14) (actual time=38927.822..43965.577 rows=407181 loops=1)
   Output: upi
   Workers Planned: 2
   Workers Launched: 2
   Buffers: shared hit=1265727 read=1702515
   I/O Timings: read=36.660
   ->  Parallel Seq Scan on public.rna  (cost=0.00..3153533.71 rows=106010 width=14) (actual time=38924.249..43688.330 rows=135727 loops=3)
         Output: upi
         Filter: (rna."timestamp" > '2021-01-01'::date)
         Rows Removed by Filter: 11722942
         Buffers: shared hit=1265727 read=1702515
         I/O Timings: read=36.660
         Worker 0: actual time=38908.360..43841.438 rows=120508 loops=1
           Buffers: shared hit=463939 read=561349
           I/O Timings: read=13.017
         Worker 1: actual time=38936.741..43374.967 rows=172038 loops=1
           Buffers: shared hit=377612 read=564988
           I/O Timings: read=11.924
 Planning Time: 0.112 ms
 Execution Time: 44001.385 ms
색인이 없으면 전체 테이블을 스캔하거나 섹션을 스캔하는 것 외에 다른 선택이 없습니다.이것은 길지만 자동으로 병렬되므로 인스턴스 형태 및 입출력 처리량에 따라 달라집니다.

postgres=> create index demo_index on rna(timestamp);
CREATE INDEX
시간stamp열에 색인을 만들 것입니다.where 자구에서 이 색인을 사용합니다.

postgres=> explain (analyze,verbose,buffers) select upi from rna where timestamp > date '2021-01-01';

                                                               QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
 Index Scan using demo_index on public.rna  (cost=0.56..236038.54 rows=254424 width=14) (actual time=0.018..237.076 rows=407181 loops=1)
   Output: upi
   Index Cond: (rna."timestamp" > '2021-01-01'::date)
   Buffers: shared hit=34667 read=28
 Planning Time: 0.172 ms
 Execution Time: 260.792 ms

이것은 색인 스캔입니다: my where 자구의 시간 범위가 색인 범위 스캔으로 변환됩니다. B-트리 구조를 사용하여 이 값의 첫 페이지로 이동하고, 링크에 따라 다음 페이지로 이동합니다. 끝날 때까지.이 색인 항목들은 선택한 열의'upi '를 얻기 위해 테이블에 있는 페이지를 인용합니다.좋은 집단 때문에, 이것은 여기에서 정상적이지만, 그것은 더 나쁠 수도 있다.만약 이것이 관건적인 용례라면 우리는 더욱 잘 할 수 있다.

postgres=> create index demo_covering_index on rna(timestamp, upi);
CREATE INDEX
이것은 내가 색인에 "upi"열을 추가한 또 다른 색인입니다.

postgres=> explain (analyze,verbose,buffers) select upi from rna where timestamp > date '2021-01-01';

                                                                     QUERY PLAN

---------------------------------------------------------------------------------------------------------------------------------------------------------
 Index Only Scan using demo_covering_index on public.rna  (cost=0.56..9488.99 rows=254424 width=14) (actual time=0.017..57.300 rows=407181 loops=1)
   Output: upi
   Index Cond: (rna."timestamp" > '2021-01-01'::date)
   Heap Fetches: 0
   Buffers: shared hit=4464
 Planning Time: 0.182 ms
 Execution Time: 80.701 ms
현재, 색인 잎에 대한 같은 접근은 테이블에서 얻을 필요가 없습니다. 왜냐하면 uid 열도 테이블에 저장되어 있기 때문입니다.이것은 색인 검색만 하는 것입니다.데이터베이스 어휘표에서 이 인덱스를 덮어쓰기 인덱스라고 부른다.그리고 읽기 전용 버퍼가 4000개에 불과해서 캐시 적중으로부터 더 많은 기회를 얻을 수 있다.
DynamoDB 용어는 projection입니다.관계 데이터베이스에서 투영은 조회에서 열 서브집합을 선별하는 작업입니다.따라서, 이것과 반대로, 우리는 색인을 저장할 열의 초집합 (서브집합이 아니라) 을 저장합니다.

create index demo_partial_index on rna(timestamp, upi) where timestamp > date '2021-01-01';
이것은where 자구가 있는 또 다른 색인입니다.이것은 SQL 데이터베이스에서 부분 인덱스라고 합니다. 모든 줄이 인덱스되는 것은 아닙니다.예를 들어, 여기서는 행 라이프 사이클이 원인일 수 있습니다.새로운 데이터에 대해 우리는 특정 날짜를 조회한다.오래된 데이터에 대해서는 스캔이 더 좋은 범위가 더 넓다(예를 들어 연도별 구분).

postgres=> explain (analyze,verbose,buffers) select upi from rna where timestamp > date '2021-01-01';

                                                                    QUERY PLAN

--------------------------------------------------------------------------------------------------------------------------------------------------------
 Index Only Scan using demo_partial_index on public.rna  (cost=0.42..8856.78 rows=254424 width=14) (actual time=0.016..52.719 rows=407181 loops=1)
   Output: upi
   Heap Fetches: 0
   Buffers: shared hit=4462
 Planning Time: 0.244 ms
 Execution Time: 76.214 ms
주의해라, 나는 이곳에서 같은 조회를 실행한다.관계 데이터베이스에서 인덱스의 유지보수와 사용은 투명하다.너는 그들에게 명확하게 물어볼 필요가 없다.항상 논리적 보기 (테이블 또는 그 위의 보기) 를 조회하면, 조회 계획기가 가장 좋은 접근 경로를 찾을 것입니다.여기서는 색인이 더 작고 접근이 더 싸기 때문에 이걸 선택했습니다.따라서 색인 검색만 하는 것 외에 일부 색인에도 도움이 됩니다.범위 스캔에 있어서, 차이는 결코 크지 않다. 왜냐하면 B 트리 인덱스가 이미 매우 유효하기 때문이다.그러나 비교적 큰 표에 대해서는 색인의 깊이가 비교적 작다.중요한 것은 이 부분의 색인에 속하지 않는 줄의 업데이트는 색인 유지 보수 비용을 가져오지 않는다는 것이다.
DynamoDB 용어, 특히...비어 있지 않고 sparse index입니다.데이터베이스 개념에서 희소 인덱스는 다르다.그러나 이것은 PostgreSQL에서 설명하기 어렵다. 왜냐하면 색인은 항상 밀집되어 있기 때문이다.
AWS Aurora가 MySQL과 호환되는 경우 동일한 가능성이 없습니다.MySQL에는 부분 인덱스가 없습니다.그러나 메인 키를 보면 색인을 볼 수 없다.인노DB는 실제적으로 테이블을 색인 구조에 저장합니다. (모든 열로 확장된 덮어쓰기 색인과 같습니다.)물리적 순서로 배열되어 있기 때문에 추가 색인 구조가 필요하지 않습니다.B나무의 잎은 시계이고 나뭇가지는 색인이다.이 인덱스는 밀집되어 있지 않습니다. 항목마다 인덱스를 작성할 필요가 없습니다.모든 내용이 질서정연하기 때문에, 모든 페이지는 첫 번째 값만으로도 충분하다.이것이 바로 데이터베이스에 있는 희소한 인덱스다.희소 인덱스는 주 인덱스, 즉 표의 물리적 조직을 정의할 수 있는 인덱스에만 적용됩니다.그러나 DynamoDB는 용어인'희소함'만 2단계 인덱스에 사용하고 그 중 하나는 하나의 항목에 존재하지 않는다(주키 속성은 필수). 그리고 인덱스를 하지 않는다. 마치 관계 데이터베이스에서 말하는 일부 인덱스와 같다.
RDBMS와 NosQL은 통상적으로 상반된다. 그들은 많은 비슷한 점이 있다. RDS에 JSON 문서를 저장하고 메인 키에 이 표들을 해시 구역으로 나누며 NosQL 데이터 구조를 가진다.SQL과 유사한 API(예: PartiQL)를 사용하여 NoSQL 데이터베이스를 질의할 수 있습니다.나는 두 API가 마이크로서비스와 분포식 인프라를 분리하기 위해 같은 집합 데이터 플랫폼을 사용할 수 있다고 생각한다.실제로 오로라와 다이나모DB의 저장 디자인은 비슷한 점이 있다.가장 큰 차이점은 NosQL이 말한 '최종 일치성' 이지만, 이것은 다음 글의 주제이다.어휘의 차이는 NoSQL 문장에서 시작되었고 용어인'SQL'을 강력한 유형, 관계 모델링, 성명성 언어 조회, ACID 속성 등의 보호 우산으로 사용했다.그래서 가장 중요한 것은 이 용어 뒤의 개념을 이해하는 것이다.결론:
  • RDS의 투영으로 SELECT
  • 읽기 제한
  • DynamoDB의 투영은 색인에 더 많은 열을 추가하여 항목별 테이블 접근을 피한다
  • RDS의 덮어쓰기 인덱스는 인덱스에 더 많은 열을 추가하여 정렬할 필요가 없고 테이블 접근을 피한다
  • RDS의 일부 인덱스는 줄의 하위 집합 유지보수 인덱스 항목으로만 작은 B 트리
  • 를 얻을 수 있습니다.
  • DynamoDB의 희소 인덱스는 속성이 존재하지 않는 2단계 인덱스 항목
  • 을 돌아서 부분 인덱스
  • 물리적 순서표
  • 로 인해 RDS의 희소 인덱스는 밀집된 메인 인덱스 항목을 피했다

    좋은 웹페이지 즐겨찾기