왜 그런지 알아보기 전에 카산드라의 데이터 저장구조에 대해서 보자.
다음과 같은 테이블을 생성했다.
CREATE TABLE test.test_tbl (
col1 text,
col2 text,
col3 text,
col4 text,
PRIMARY KEY (col1, col2)
);
pk를 col1, col2로 지정했다. pk는 multiple column이 가능하다.
카산드라의 경우 partition key, clustering key가 존재하는데 pk를 지정할 때 partition key, clustering key 순으로 지정한다.
partition key는 hash값에 따라 각 노드에 분산시키고 이를 괄호로 묶어주어 분산시킬 수 있다. 이어서 나오는 키는 clustering key로 노드에서의 데이터 정렬이다.
카산드라는 where절에 partition key를 지정해서 노드를 찾아가야한다. design essue이다.
where col1 = '1'은 잘 된다는 의미이다. 하지만 where col2 = '1'이나 col3 = '1' 등 partition key를 지정을 하지 않으면 다음과 같은 에러가 뜬다.
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING"
그럼 혹시 인덱스를 만들면 될까?
CREATE INDEX idx_test_tbl_col2 ON upsell.test_tbl ( col2 );
이 경우에는 select * from test_tbl where col2 = '1'; 이 잘 동작한다.
하지만 select * from test_tbl where col2 = '1' and col3 = '1'; 동일한 에러가 뜬다.
그렇다면 col3에도 동일하게 인덱스를 만들어주면 where col2 = '1' and col3 = '1'가 될까 테스트해보자.
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING"
역시 동작하지 않는다.
datastax 공식문서에 보면 다음 내용이 있다.
이를 피하기 위해서는 ALLOW FILTERING 옵션을 사용하라고 한다.
select * from test_tbl where col2 = '1' and col3 = '1' ALLOW FILTERING;
하지만 allow filtering은 클러스터의 모든 노드에 query를 날리기 때문에 성능제약이 있다. 카산드라의 경우 hash key를 활용하기 때문에 성능상의 이점이 있는데 이를 포기하는 쿼리가 되는 것이다.
댓글 없음:
댓글 쓰기