2014-11-04 7 views
1

내가 다음 표와 보조 인덱스가 정의한 말 :2 차 색인의 Cassandra SELECT는 항상 파티션 키를 기준으로 정렬됩니까?

CREATE TABLE ItemUpdates (
    time   timestamp, 
    item_name text, 
    item_context text, 
    item_descr text, 
    tags   map<text, int>, 
    PRIMARY KEY ((time, item_name, item_context)) 
); 

CREATE INDEX ItemUpdateByName 
    ON ItemUpdates(item_name); 

CREATE INDEX ItemUpdateByContext 
    ON ItemUpdates(item_context); 

CREATE INDEX ItemUpdateByTag 
    ON ItemUpdates(KEYS(tags)); 

데이터 모델에 대한 일반 배경 정보 : 항목은 컨텍스트 내에서 고유 한 이름을 가지고 있으므로 (ITEM_NAME의는 item_context는) 항목에 대한 자연의 열쇠입니다 . 태그는 그들과 관련된 어떤 가치가 있습니다.

내 응용 프로그램의 자연 쿼리는 "특정 태그가있는 항목 X의 모든 업데이트를 표시합니다"입니다. 이 변환에 :

SELECT * FROM ItemUpdates 
    WHERE item_name='x' 
     AND item_context='a' 
     AND tags CONTAINS KEY 't'; 

내가 클러스터가 Murmur3Partitioner를 사용하지만, 결과는 시간 순서 온 것을 알 일부 쿼리를 시도

. 이것은 카산드라가 보조 색인을 넓은 행으로 저장하고 해당 열이 이름순으로 정렬된다는 것을 고려할 때 의미가 있습니다.

(1) (n) (집합) 색인화 된 열을 선택할 때 Cassandra는 항상 파티션 키순으로 정렬 된 행을 반환합니까?

  • 항목 X
  • 에 300 최신 업데이트를 가져 오는 날짜 D 있기 때문에, 항목 X에 대한 모든 업데이트를 가져 오기 :

    나는이 흥미를 찾을 이유는 내 응용 프로그램에서 다른 자연 쿼리가 포함되어 있다는 것입니다

ItemUpdates에서 select 문에 ORDER BY time DESC 절을 추가하면 "2 차 인덱스가있는 ORDER BY는 지원되지 않습니다."라는 오류 메시지가 나타납니다.

(2) 색인 생성 된 열을 선택하여 쿼리의 범위를 좁힐 때 파티션 키에서 범위 쿼리를 수행 할 수 있습니까?

답변

2

카산드라를 타고 가야하는 자연스러운 "자동"분류는 넓은 행의 열입니다. murmur3을 사용할 때 파티션은 임의의 분포 (afaik)를 엉망으로 만드는 것처럼 "정렬"되지 않습니다. 인덱스는 "숨겨진"테이블의 각 노드에 넓은 행으로 저장됩니다. 인덱스의 필터를 사용하면 "노드"의 "파티션"에 도달하고 그 값은 해당 노드의 일치하는 행에 해당하는 해당 파티션의 행입니다. 다른 데이터 세트와 다른 열을 사용하여 쿼리를 시도하십시오. 어쩌면 가지고있는 데이터로 인해 결과가 정렬 될 수 있습니다.

(2) 파티션 키가 아닌 클러스터링 키에 대해서만 범위 쿼리를 수행 할 수 있습니다. 일반적으로 효율적인 질의를 위해서는 하나 또는 몇 개의 파티션을 공격하고, 클러스터링 키에 대한 클러스터링 키/범위 쿼리에서 인덱스/필터를 필터링해야합니다. 파티션을 히트하지 않으려하면 클러스터 전체 작업이되며 일반적으로 그렇게되지는 않습니다. 클러스터 전체 분석 (ala map reduce style)을 원하면 Apache Spark를 살펴보십시오. 스파크 카산드라 통합은 꽤 좋으며 점점 좋아지고 있습니다.

+0

감사합니다. 따라서 (1)에 대한 답은 "아니오"입니다. 귀하의 제안을 확인하고 실제로 : 결과가 정렬되지 않았습니다. 나에게 나타난다 나는 아직 2 차 색인의 내부를 완전히 이해하지 못한다. 색인은 넓은 행의 CF이고, 넓은 행의 파티션 키는 색인 된 값이고, '목표'행의 파티션 키는 열 이름 (값 없음)으로 간주됩니다. 결과는 인덱스 조회 결과가 파티션 키의 정렬 된 (!) 목록이됩니다 (열은 이름순으로 정렬되기 때문에). – Rinke

+0

ItemUpdates의 첫 번째 버전은'((item_name, item_context), time)'을 (를) PK로 가지고 있습니다. 내 질문의 글 머리 기호 쿼리는 당연히 당연한 것입니다.그러나 몇 가지 계산을 수행하면 일정 시간이 지나면 열이 너무 넓어 져서 다르게 분할해야한다는 것을 알게되었습니다. 어떤 제안? – Rinke

+0

버킷을 도입 할 수 있습니다. 예를 들어 ((이름, 컨텍스트, 연도), 시간). 그것은 당신에게 1 년에 1 행을 줄 것입니다. 그게 너무 많으면 월 단위로 해낼 수 있습니다. ((이름, 컨텍스트, 월 단위), 시간). 클라이언트 측에서 더 많은 쿼리를 의미 할 수도 있지만 일반적으로 n * 2ms 쿼리는 큰 맵 축소보다 저렴합니다. – ashic