중급6분 분량

DynamoDB 스파스 인덱스

희소 인덱스는 해당 항목을 포함하는 항목만 보유하는 보조 인덱스입니다. 주요 속성 — 거대한 테이블의 작고 핫한 하위 집합이 자체적으로 사용됩니다. 사전 필터링되어 바로 쿼리할 수 있는 컬렉션입니다.

수백만 개의 행이 있지만 하루 종일 실행하는 쿼리는 아주 작은 부분, 즉 미결제 지원 티켓, 미지급 송장, 검토 대상 계정.

해당 조각을 필터링하면 여전히 전체 테이블을 검색하고 모든 읽기에 대해 비용을 청구합니다. 에이 희소 인덱스는 대신 인덱스 자체를 작게 만듭니다.

DynamoDB의 희소 인덱스란 무엇입니까?

희소 인덱스는 해당 키 속성을 포함하는 항목만 보유하는 보조 인덱스입니다. DynamoDB는 해당 키가 누락된 항목을 건너뛰기 때문에 원하는 항목(미결제 티켓, 미지급 송장)만 작성하는 키를 생성하면 인덱스가 정확한 하위 집합이 됩니다. 그런 다음 쿼리는 필터 없이 읽기 용량을 낭비하지 않고 바로 읽습니다.

  • 보조 인덱스는 해당 키가 있는 항목만 인덱싱합니다. 항목이 색인에 들어가지 않습니다. 자리 표시자나 null 행이 없습니다.
  • 그래서 당신은 원하는 아이템만 가지고 다닐 수 있는 열쇠를 발명했습니다. 당신이 가지고 있는 아이템에 그것을 적어주세요. 쿼리를 실행하고 나머지는 제거하세요. 인덱스는 정확히 해당 하위 집합이 됩니다.
  • 쿼리는 필터 없이 하위 집합만 읽습니다. 해당 크기는 작은 핫을 추적합니다. 테이블 합계가 아니라 설정합니다.
  • REMOVE은 블랭킹이 아닌 레버입니다. 빈 문자열은 유효한 인덱스가 아닙니다. key — DynamoDB는 ValidationException으로 전체 쓰기를 거부합니다. 속성을 삭제하세요.

문제: 필터링으로 읽은 내용이 저장되지 않습니다.

SQL에서 WHERE 절이 작업 범위를 좁힌다고 가정합니다. DynamoDB의 FilterExpression는 그렇지 않습니다. 항목을 읽기 전이 아닌 에 실행됩니다.

AWS Developer Guide, "쿼리는 필터 여부에 관계없이 동일한 양의 읽기 용량을 소비합니다. 표현이 존재합니다." — 조사한 모든 항목에 대해 비용을 지불한 다음 해당 항목을 던집니다. 일치하지 않는 거리.

따라서 500만 개의 티켓 중 50개가 열려 있으면 필터링된 Query/Scan가 읽혀집니다. 수백만 달러를 통해 그 50개를 당신에게 건네줍니다.

이것이 바로 "내 스캔 비용이 왜 이렇게 비싼가"라는 스레드 뒤에 숨은 기본 요소입니다. query vs. scan에는 전체 비용 그림이 있습니다.

희소 인덱스는 인덱스 자체를 작게 만들어 이를 회피합니다.

희박성이 작동하는 방식

보조 인덱스 실제로 인덱스 키가 있는 항목만 인덱스합니다. 속성.

AWS docs on sparse indexes 자세히 설명: DynamoDB는 해당 항목이 있는 경우에만 보조 인덱스에 항목을 씁니다. 인덱스의 주요 속성을 전달하므로 거의 설정되지 않는 속성에 대한 인덱스는 그대로 유지됩니다. 당연히 작습니다.

항목에서 GSI의 파티션 키(또는 정렬 키)가 누락되고 DynamoDB는 그렇지 않습니다. 인덱스에 쓰세요. 자리 표시자 없음, null 행 없음 — 항목이 없습니다.

"기본적으로 부재"가 전체 트릭입니다. status 속성을 색인화하지 마세요 그 모든 품목이 운반됩니다. 원하는 항목만 표시하는 속성을 만들어 보세요. 쿼리는 전혀 수행되지 않습니다 .

그러면 색인은 정확히 해당 항목의 깨끗한 목록이 되며, 이에 대한 Query 필터도 없고 용량 낭비도 없습니다.

키를 운반하는 항목만 교차하는 인덱스를 제공하는 기본 테이블을 생각해 보세요.

제거됨 제거됨스파스 GSI (open만)OpenOpen베이스 테이블 (모든 아이템)Open: 있음Open: 있음Closed: 없음Closed: 없음

키가 있는(열린) 항목만 인덱스에 복제됩니다. 닫힌 항목은 절대 입력되지 않습니다.

이는 키 형성 사고방식과 동일합니다. single-table design: 키는 다음을 위해 만든 도구입니다. 특정 액세스 패턴이 아닌 데이터의 충실한 미러링입니다.

실제 사례: "오픈 티켓만"

지원 티켓 테이블을 가져 가십시오. 기본 테이블은 ID로 티켓을 가져오기 위한 키입니다. 고객의 티켓을 나열합니다.

PKSKattributes
TICKET#a91fDETAILsubject, body, priority, openState
CUSTOMER#88TICKET#a91fsubject, priority, openState

테이블 수명 동안 대부분의 티켓은 종료됩니다. 하지만 대시보드 쿼리는 상담원이 하루 종일 하는 일은 "모든 공개 티켓을 오래된 것부터 보여주세요"입니다. — 몇 개 수백만 개 안에 수백 개의 행이 숨어 있습니다.

희소 인덱스 이동: 파티션 키 openBucket 및 정렬 키를 사용하여 를 정의합니다. openedAt, 오픈 티켓에는 openBucket만 기재하세요. 다음과 같은 경우에 설정하세요. 티켓이 생성되었습니다. REMOVE 티켓이 해결되면 완료됩니다.

PKSKopenBucketopenedAt
TICKET#a91fDETAILOPEN2026-06-23T09:14:00Z← open: in the index
TICKET#b02cDETAILOPEN2026-06-22T16:40:00Z← open: in the index
TICKET#77deDETAIL(absent)2026-05-30T11:02:00Z← closed: NOT in the index

a91fb02c티켓은openBucket를 포함하므로 GSI에 거주합니다. 티켓 77de이 해결되었고 openBucket가 제거되었으므로 자동으로 삭제되었습니다. 는 대시보드는 이제 하나의 저렴한 쿼리입니다.

Query  IndexName = "open-tickets-index"
KeyConditionExpression: openBucket = "OPEN"
ScanIndexForward: true        # oldest first

공개 티켓만 읽습니다. 티켓이 종료되면 인덱스가 저절로 줄어듭니다. size는 open 모집단을 추적하며 총계는 추적하지 않습니다.

하나의 정적 파티션 값("OPEN")은 집합이 그대로 유지되기 때문에 여기서는 괜찮습니다. 작다. 거대한 공개 집합에는 분할된 파티션 키가 필요하지만 "작은 하위 집합" index는 정확히 하나의 값이 올바른 호출인 위치입니다.

이를 작동시키는 전환은 단일 입니다. 티켓이 해결될 때의 속성입니다.

REMOVE 절과 읽기 측에 대해 입력된 키 조건을 프로토타입화합니다. DynamoDB Expression Builder 대신 ExpressionAttributeNames:val 자리 표시자를 직접 손으로 조립합니다.

DynoTable에서 해보기

희소 인덱스의 어려운 부분은 어떤 항목이 그것을 만들었는지 _보는 것_입니다 조용히 빠진 인덱스에.

DynoTable을 사용하면 테이블 보기를 보조 인덱스로 전환하고 정확하게 볼 수 있습니다. 채워진 하위 집합. 해결된 티켓이 실제로 남아있는 것을 확인할 수 있습니다. 낡은 열쇠를 가지고 머뭇거리는 대신 open-tickets-index.

DynoTable에서 open-tickets 희소 GSI로 본 지원 티켓 테이블 — openBucket 키를 가진 항목만 보입니다.
DynoTable에서 open-tickets 희소 GSI로 본 지원 티켓 테이블 — openBucket 키를 가진 항목만 보입니다.

함정과 다음 단계

시청할 몇 가지 사항:

  • 키를 제거하세요. 비우지 마세요. 빈 문자열은 유효한 인덱스 키가 아닙니다. — openBucket = "" 쓰기가 ValidationException과 함께 실패하므로 해당 항목은 절대로 그것으로 색인을 생성했습니다. 색인에서 항목을 삭제하려면 속성을 REMOVE해야 합니다.
  • 지수는 입니다. GSI는 비동기식으로 업데이트되므로 방금 해결된 티켓이 잠시 동안 계속 나타날 수 있음 - GSI 읽기 support eventual consistency only. "이 티켓이 지금 열려 있습니까?"라고 믿지 마십시오.
  • 마인드 속성. 인덱스의 Query는 속성이 투영됩니다. 대시보드에 주제와 우선순위가 필요한 경우, 투영하거나 전체 기본 품목에 대해 추가로 GetItem를 지불하세요.
  • GSI와 LSI 모두 희소할 수 있습니다 — 레버는 동일합니다. 인덱스의 색인을 생성하고 싶지 않은 항목의 정렬 키입니다. 일반적으로 GSI가 더 적합합니다. 하지만 테이블 생성 후에 이를 추가하고 자체 키 스키마를 제공할 수 있습니다. 용량. GSI vs. LSI은 상충관계를 분해합니다.

희소 인덱스는 모델에서 가장 오래된 아이디어 중 하나입니다. 원본 2007 Amazon Dynamo paper 알려진 대량 액세스 패턴을 저렴하게 제공하기 위해 상점을 구축했습니다.

희소 인덱스는 바로 다음과 같습니다. 일반 쿼리가 아무 것도 읽지 않도록 키를 구성합니다. 필요하지 않습니다.

실제 download DynoTable를 만들고 검사하려면 다음을 가리킵니다. 테이블을 만들고 데이터 보기를 희소 GSI로 전환합니다. 하위 집합 업데이트를 다음과 같이 확인하세요. 항목은 인덱스 키를 얻고 잃습니다.

업데이트됨