카산드라의 SELECT문은 일반 RDB의 SELECT문과는 다른 점들이 있습니다. 카산드라 조건 조회의 특징들을 알아보겠습니다.
예제 테이블
CREATE TABLE chat (
chatroom_id int,
message_id int,
content text,
user_id int,
PRIMARY KEY (chatroom_id, message_id)
);
파티션키(Partition Key)는 charoom_id이고, 클러스터링 키(Clustering Key)는 message_id 입니다.
Where 절에는 파티션 키(Partition Key)와 클러스터링 키(Clustering Key)에만 사용할 수 있습니다.
SELECT * FROM chat WHERE chatroom_id = 1; (O)
SELECT * FROM chat WHERE content = '안녕'; (X)
카산드라는 파티션키에 따라 데이터를 어떤 노드에 배치할지 정합니다. 그런데 non-primary column에 조건 조회를 하려고 하면, 분산 된 모든 노드에 대한 쿼리를 실행하겠다는 뜻으로, 비효율이 발생합니다. 카산드라는 이러한 비효율적 방식을 사전에 차단하고 아래와 같은 오류를 발생시킵니다.
Cannot execute this query as it might involve data filtering and thus may have unpredictable performance.
파티션 키가 복합키라면 복합키로 지정한 칼럼을 모두 사용해야만 조회할 수 있습니다.
PRIMARY KEY ((col1, col2), col3, col4);
WHERE col1 = 1 and col2 = 1; (O)
WHERE col1 = 1; (X)
WHERE col2 = 1; (X)
분산 배치 된 노드를 찾아가기 위해서는 복합키로 지정한 모든 칼럼을 모두 조회해야만 데이터를 찾을 수 있습니다.
클러스터링 키에 조건조회를 하려면, 파티션 키를 먼저 필터링을 하고 클러스터링 키를 조회해야 합니다.
SELECT * FROM chat WHERE chatroom_id = 1 and message_id = 1; (O)
SELECT * FROM chat WHERE message_id = 1; (X)
클러스터링 키가 여러개 이고, N번째 클러스터링 칼럼에 조회하려면, 앞에 선행되는 N-1개의 칼럼을 모두 조회 조건에 명시해야합니다.
PRIMARY KEY ((col1, col2), col3, col4);
WHERE col1 = 1 and col2 = 1 and col3 = 1 and col4 = 1; (O)
WHERE col1 = 1 and col2 = 1 and col4 = 1; (X)
WHERE col4 = 1; (X)
정렬(ORDER BY)
정렬은 클러스터링 키에만 사용이 가능하고, 조회 쿼리가 하나의 노드로 한정(파티션 키로 되었을 경우에만 사용이 가능합니다.
SELECT * FROM chat WHERE chatroom_id = 1
ORDER BY message_id desc;
만약 여러 클러스터링 키의 정렬을 해야한다면, 선행되는 클러스터링키를 먼저 정렬해야하고 정렬되는 칼럼은 모두 ASC 또는 DESC로 하나로 통일해야 합니다.
PRIMARY KEY ((col1, col2), col3, col4);
ORDER BY col3 ASC, col4 ASC; (O)
ORDER BY col4 ASC; (X)
ORDER BY col3 ASC, col4 DESC; (X)
그룹(GROUP BY)
카산드라는 파티션 키와 클러스터링 키에 대하여 그룹화 하여 조회 할 수 있습니다. N번째 칼럼에 대하여 그룹을 사용하고 싶다면, 앞에 선행되는 N-1 개의 칼럼을 모두 그룹화하여햐 합니다.
GROUP BY col1, col2; (O)
GROUP BY col1, col2, col3, col4; (O)
ORDER BY col3; (X)
범위 검색
카산드라에서 범위 검색은 클러스터링 키에 대해서만 조회할 수 있습니다.
PRIMARY KEY ((col1, col2), col3, col4);
WHERE col1 = 1 and col2 > 5; (X)
WHERE col1 = 1 and col2 = 1 and col3 > 5; (O)
non-primary colmn에 검색해야 할 경우에는 어떻게 해야할까?
지금까지 알아본 것처럼 카산드라는 파티션 키와 클러스터링 키의 역할과 특성에 따라서 지원하는 연산자가 제한적입니다. Primary Key가 아닌 칼럼에 조회해야 하는 경우에는 Secondary Index를 사용하는 방법과 Allow Filtering을 사용하는 방법이 있습니다.
Secondary Index
CREATE INDEX myindex on chat(content);
SELECT * FROM chat WHERE content = '안녕';
SELECT * FROM chat WHERE chatroom_id 1 and content = '안녕';
non-primary column을 이용해서 데이터를 조회하기 위해 index를 생성하면 됩니다. 생성된 Secondary Index에 조회를 할 경우 모든 노드에 쿼리를 요청한 후 결과를 merge하여 반환합니다. 그렇기 때문에 카산드라에서 Secondary Index를 이용한 쿼리는 무거운 작업입니다.
그리고 Secondary Index 칼럼에 in 연산자, order by 및 범위 검색이 불가능합니다. 또한 Secondary Index와 파티션 키 칼럼에 같이 검색할 경우 모든 파티션 키를 명시해야 조회가 가능합니다.
Allow Filtering
non-primary column에 범위 검색 또는 정렬 등을 해야할 때는 쿼리 뒤에 Allow Filtering 붙혀주면 조회할 수 있게 됩니다.
SELECT *
FROM chat
GROUP BY user_id
ALLOW FILTERING;
하지만 Allow Filtering 쿼리는 전체 인덱스를 스캔하기 때문에 성능이 저하될 수 있습니다.
스키마를 디자인 할 때 검색해야 하는 칼럼들을 미리 잘 설계하자.
'Database > NoSQL' 카테고리의 다른 글
[Cassandra] DBeaver에 카산드라 드라이버 설치 및 연결 (0) | 2023.06.05 |
---|---|
[Cassandra] Cassandra 설치 방법 (0) | 2023.06.05 |
[Cassandra] 기본 키, 파티션 키, 클러스터링 키 (0) | 2023.05.24 |
[Cassandra] 카산드라 기본 개념 (0) | 2023.05.23 |
[Cassandra] Apache Cassandra 란? (0) | 2023.05.19 |