중급6분 분량

DynamoDB 인덱스 예측

보조 인덱스를 생성할 때 DynamoDB는 전체 항목을 자동으로 복사하지 않습니다. 그것에. 복사할 대상**, 즉 인덱스의 예측을 선택합니다. 너무 적게 골라라 쿼리는 나머지를 가져오기 위해 두 번째 읽기를 수행합니다. 모든 것을 선택하고 추가 비용을 지불합니다 모든 업데이트에 대한 저장 및 쓰기 비용. 인덱스 생성 시 한 번 설정한 절충안입니다. 그리고 함께 살아요.

(이것을 속성을 다듬는 프로젝션 표현식과 혼동하지 마십시오. 단일 읽기 반환. 이 페이지는 인덱스가 물리적으로 저장하는 것에 관한 것입니다. 다른 하나는 projection expressions입니다.)

DynamoDB 인덱스 예측이란 무엇입니까?

프로젝션은 DynamoDB가 기본 테이블에서 보조 인덱스로 복사하는 속성 세트입니다. KEYS_ONLY(키만), INCLUDE(키와 명명된 속성 목록) 또는 ALL(전체 항목)의 세 가지 유형 중 하나를 선택합니다. 프로젝션이 많을수록 기본 테이블 가져오기 횟수는 줄어들지만 스토리지 및 쓰기 비용은 높아집니다.

  • 프로젝션은 보조 인덱스에 복사된 속성 세트입니다.
  • KEYS_ONLY — 테이블 및 인덱스 키만. 가장 작고 저렴합니다.
  • INCLUDE — 키와 선택한 추가 속성의 이름이 지정된 목록.
  • ALL — 항목의 모든 속성입니다. 가장 큰; 쿼리에는 기본 테이블이 필요하지 않습니다.
  • 예측되지 않은 속성은 GSI에서 사용할 수 없습니다 — 앱 자체 기본 테이블 읽기를 실행해야 합니다. (LSI만이 다음에 대한 비투영 속성을 가져옵니다. 추가 읽기 비용이 발생합니다.)
  • 더 많은 프로젝션 = 더 많은 스토리지 + 더 많은 쓰기 비용, 모든 기본 테이블 쓰기 이후 인덱스에 전파됩니다.

문제: 두 번 읽게 만드는 색인

우선순위에 따라 공개 티켓을 나열할 수 있는 GSI를 갖춘 지원 데스크를 운영한다고 가정해 보겠습니다. 당신은 그것을 희박하게 유지하기 위해 KEYS_ONLY을 계획합니다. 쿼리는 빠르게 반환되지만 티켓 ID 및 대기열 화면에는 각 티켓의 제목, 담당자 및 연령이 필요합니다.

이제 코드는 기본 테이블에 대해 두 번째 읽기를 수행하여 모든 데이터를 수화합니다. 결과. 여러분이 디자인한 "하나의 쿼리"는 실제로 쿼리에 N 가져오기를 더한 것이며, 절약하려고 했던 대기 시간과 비용이 바로 돌아왔습니다. 프로젝션이 너무 얇았습니다. 액세스 패턴에 대해

각 투영 유형이 복사하는 것

베이스 아이템: + subject +assignee + age + bodyKEYS_ONLY: 키만INCLUDE: + subject, assignee,ageALL: 모든 속성
  • KEYS_ONLY 기본 테이블 키 인덱스 키만 저장합니다. 다음과 같은 경우에 사용하세요. 쿼리는 항목이 일치하는 어떤_ 항목만 알아야 하며 다른 곳에서 세부 정보를 가져옵니다. 또는 전혀 그렇지 않습니다.
  • INCLUDE 키와 사용자가 명명한 고정 속성 목록을 저장합니다. 달콤한 Spot: 쿼리가 렌더링해야 하는 필드만 정확하게 투영합니다.
  • ALL 항목 전체를 복사합니다. 쿼리는 인덱스에서 완전히 자체적으로 제공됩니다. 전체 항목의 스토리지를 복제하고 여기에 처리량을 쓰는 비용입니다.

지원 데스크 대기열의 경우 subject, assigneeage이 포함된 INCLUDE는 올바른 호출 - 대기열은 두 번째 가져오기 없이 인덱스에서만 렌더링됩니다. 티켓의 큰 body을 인덱스에 복제합니다.

거래하는 비용

당신이 프로젝트하는 모든 속성은 stored a second time 기본 항목이 변경될 때마다 인덱스에 다시 작성됩니다. 그래서 관대한 ALL 자주 업데이트되는 테이블에 프로젝션하면 스토리지와 쓰기 용량이 모두 배가됩니다. 규율은 "만일의 경우를 대비하여 모든 것"이 아닌 쿼리가 읽는 내용을 계획하는 것입니다.

알아야 할 미묘함: 희소 지수를 사용하면 투영은 여전히 인덱스 키가 있는 항목 — 따라서 INCLUDE/ALL sparse index는 지수 자체가 크기 때문에 작게 유지됩니다. 작다. 스토리지의 무게를 측정하고 프로젝션에 대한 승수를 쓰기 DynamoDB pricing calculator, 조립 인덱스 쿼리 자체를 사용하여 DynamoDB expression builder.

DynoTable에서 프로젝션 보기

DynoTable은 각 테이블의 보조 인덱스를 나열하고 직접 쿼리할 수 있도록 해줍니다. 하나. 기본 테이블과 GSI에 대해 동일한 액세스 패턴을 실행하고 비교합니다. 결과 - 인덱스 결과에서 누락된 속성은 정확히 그 속성입니다. 투영되지 않으므로 테이블을 다시 읽지 않고도 투영 효과를 볼 수 있습니다. 정의.

DynoTable의 인덱스 선택기에서 쿼리가 어느 DynamoDB 인덱스를 통과할지 고르는 모습.
DynoTable의 인덱스 선택기에서 쿼리가 어느 DynamoDB 인덱스를 통과할지 고르는 모습.

함정과 다음 단계

  • GSI에서 프로젝션되지 않은 속성은 베이스 테이블 fetch를 의미합니다 — 쿼리가 그리는 것을 중심으로 프로젝션을 설계하세요.

  • ALL은 거의 공짜가 아닙니다 — 스토리지와 쓰기 비용을 복제합니다. 인덱스가 정말 모든 필드가 필요하기 전에는 INCLUDE를 기본으로 하세요.

  • 프로젝션은 거의 고정입니다. 인덱스를 다시 만들지 않고 GSI 프로젝션을 나중에 자유롭게 편집할 수 없습니다 — 처음에 의도적으로 고르세요.

  • 관련: GSI와 LSI희소 인덱스가 프로젝션이 실제로 얼마나 저장되는지 좌우합니다.

재설계 전에 각 인덱스가 실제로 무엇을 반환하는지 보고 싶나요? DynoTable 다운로드하고 테이블에 직접 쿼리하세요.

하이드레이션 비용: KEYS_ONLY + N번 get

지원 데스크 큐 예로 돌아갑니다. 미해결 티켓 50장을 제목·담당자·경과 시간과 함께 표시합니다.

프로젝션인덱스 쿼리후속 읽기EC RCU 스케치(베이스 2 KB)
KEYS_ONLY키 50개 반환50 × GetItem인덱스 ~50 RCU + 베이스 ~50 RCU
INCLUDE subject, assignee, age자급자족 50행없음인덱스 ~50 RCU만
ALL전체 복사 50개없음인덱스 ~50 RCU, 스토리지·쓰기 증폭↑

정확한 숫자는 프로젝션 속성 크기에 달립니다 — 샘플 티켓을 아이템 크기 계산기에 붙여 큐 깊이를 곱하세요. 목록에 거의 안 나오는 큰 body가 있다면 UI 필드만 나열한 INCLUDEALL보다 나은 경우가 많습니다.

LSI 프로젝션 fetch 동작

LSI만 쿼리 중 프로젝션되지 않은 속성을 베이스 테이블에서 선택적으로 가져올 수 있습니다(추가 읽기 비용). GSI는 절대 하지 않습니다 — 빠진 속성은 앱이 베이스에 GetItem해야 합니다. 그 차이 때문에 많은 GSI 설계가 처음부터 조금 더 넓은 INCLUDE로 갑니다.

나중에 프로젝션 바꾸기

GSI 프로젝션은 생성 시 고정입니다. KEYS_ONLYINCLUDE로 넓히려면 새 인덱스를 만들고, 백필하고, 트래픽을 옮긴 뒤 옛 인덱스를 지웁니다 — 출시 전에 필드를 계획하세요. LSI도 같은 제한을 공유합니다.

새 액세스 패턴을 평가할 때는 DynoTable에서 후보 인덱스를 쿼리하고 어떤 속성이 보이는지 목록화하세요 — 빈칸은 빠진 프로젝션 항목과 1:1입니다.

희소 인덱스와 짝짓기

status = open 티켓만 인덱싱하는 희소 GSI는 열린 행의 프로젝션만 보관합니다. 베이스에 닫힌 티켓이 수백만이어도 그 인덱스의 INCLUDE는 저렴합니다 — 인덱스가 그것들을 복사하지 않았습니다.

필터된 부분집합이 테이블 대비 작다면 희소 인덱스 패턴과 결합하세요.

먼저 액세스 패턴을 만드세요

CloudFormation을 건드리기 전에 쿼리 빌더로 GSI 쿼리 — 키 조건, 프로젝션 식, 필터 — 를 프로토타입하세요. 설계 논의에서는 UI가 그리는 열을 묻고, 나머지는 베이스 테이블에 둡니다.

업데이트됨