Sangwon
07/15/2026, 6:30 AMRocky
07/15/2026, 6:30 AMINDEX 구문 없이도 ORDER BY 절이나 테이블 생성 시 앞쪽에 배치한 컬럼들이 이 역할을 합니다.
* 설정 방법: `ORDER BY (컬럼1, 컬럼2, ...)`에 자주 필터링 조건(WHERE)으로 사용하는 컬럼을 넣습니다.
* 주의: 카디널리티(중복도가 낮은 정도)가 높은 컬럼을 앞쪽에 배치하는 것이 성능상 유리합니다.
2. Bitmap Index (비트맵 인덱스)
데이터의 종류가 많지 않은 컬럼(Low Cardinality)이나, 여러 조건을 조합해서 조회할 때 효과적입니다.
* 생성 방법 (테이블 생성 시):
sql
CREATE TABLE example_table (
user_id INT,
gender CHAR(1),
INDEX idx_gender (gender) USING BITMAP
)
DUPLICATE KEY(user_id)
DISTRIBUTED BY HASH(user_id);
* 나중에 추가 시: CREATE INDEX idx_name ON table_name (column_name) USING BITMAP;
3. Bloom Filter Index (블룸 필터 인덱스)
ID값처럼 종류가 매우 많은 컬럼(High Cardinality)에 대해 WHERE column = 'abc' 또는 IN 조건으로 조회할 때 성능을 크게 향상시킵니다.
* 설정 방법: 테이블 생성 시 `PROPERTIES`에 지정합니다.
sql
CREATE TABLE example_table (
order_id VARCHAR(100),
price INT
)
DUPLICATE KEY(order_id)
DISTRIBUTED BY HASH(order_id)
PROPERTIES (
"bloom_filter_columns" = "order_id" -- 여기에 컬럼 지정
);
4. 기타 특수 인덱스 (최신 버전)
* Inverted Index (역색인): 텍스트 검색(LIKE 등) 속도를 높일 때 사용합니다. (USING GIN)
* N-Gram Bloom Filter: 긴 문자열의 부분 일치 검색을 최적화할 때 사용합니다. (USING NGRAMBF)
* Vector Index: AI/벡터 유사도 검색 시 사용합니다. (USING VECTOR)
요약 가이드
1. 공통: 가장 자주 쓰는 필터 컬럼을 ORDER BY 맨 앞에 둡니다.
2. 동등 비교(=, IN): 해당 컬럼이 유니크에 가깝다면 *Bloom Filter*를, 값의 종류가 적다면 *Bitmap*을 고려하세요.
3. 텍스트 검색: LIKE '%word%' 조회가 많다면 *Inverted Index*를 고려하세요.
References
• sql-reference/sql-statements/table_bucket_part_index/CREATE_INDEX.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
• table_design/indexes/Bloomfilter_index.md
• table_design/indexes/vector_index.mdSangwon
07/15/2026, 6:31 AMRocky
07/15/2026, 6:32 AMORDER BY (Prefix Index)
StarRocks 테이블 생성 시 ORDER BY 절에 적힌 컬럼들은 데이터가 정렬되어 저장됩니다. 이 컬럼들은 자동으로 *Prefix Index*가 생성되어 WHERE 조건에 해당 컬럼이 있으면 속도가 압도적으로 빠릅니다.
* 특징: 테이블당 하나만 설정 가능.
* 팁: 가장 자주 조회 조건으로 쓰는 컬럼 3~4개를 순서대로 넣으세요.
2. MySQL의 'Secondary Index' 효과: Inverted Index (추천)
v3.3 버전부터 지원되는 *Inverted Index (GIN)*는 MySQL에서 일반 인덱스를 거는 것과 가장 유사한 효과를 줍니다. `ORDER BY`에 포함되지 않은 컬럼으로 조회할 때 성능을 대폭 높여줍니다.
* 설정 방법 (테이블 생성 시):
sql
CREATE TABLE search_table (
id BIGINT,
user_name VARCHAR(50),
city VARCHAR(20),
-- 일반적인 등호(=), 범위(>, <), IN 조건을 위한 인덱스
INDEX idx_user (user_name) USING GIN("parser" = "none")
)
DUPLICATE KEY(id)
ORDER BY (id) -- 기본 정렬 키
DISTRIBUTED BY HASH(id);
* `"parser" = "none"`의 의미: MySQL 인덱스처럼 값 전체를 그대로 인덱싱한다는 뜻입니다. (텍스트 검색이 목적이라면 english, chinese 등의 parser를 사용)
* 장점: =, !=, >, <, IN, LIKE 조건을 모두 가속할 수 있습니다.
3. 기타 인덱스 선택 기준
MySQL 스타일의 인덱스 외에 데이터 특성에 따라 아래를 선택합니다.
인덱스 종류 | 추천 상황 (MySQL 비유) | 특징
Inverted Index | 일반적인 보조 인덱스 | 가장 범용적임. 등호, 범위, LIKE 가속
Bitmap Index | 성별, 지역 등 (중복값 많음) | 데이터 종류(Cardinality)가 적을 때 매우 효율적
Bloom Filter | ID, UUID 등 (중복값 거의 없음) | 특정 값이 '없음'을 빠르게 판단하여 스캔량 감소
요약: 어떻게 걸면 될까?
1. 가장 많이 쓰는 조회 컬럼은 *`ORDER BY`*에 넣는다. (가장 중요)
2. 그 외에 자주 검색되는 컬럼은 *`INDEX ... USING GIN("parser" = "none")`*을 추가한다.
3. 이미 만든 테이블에 인덱스를 추가하고 싶다면:
sql
ALTER TABLE table_name ADD INDEX idx_name (column_name) USING GIN("parser" = "none");
References
• table_design/indexes/inverted_index.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_INDEX.md
• table_design/indexes/Bitmap_index.md
References
• table_design/indexes/inverted_index.md
• best_practices/query_tuning/schema_tuning.mdSangwon
07/15/2026, 6:32 AMRocky
07/15/2026, 6:33 AM"parser" = "none" 설정이 핵심입니다.
sql
-- 'users' 테이블의 'user_name' 컬럼에 인덱스 추가
ALTER TABLE users
ADD INDEX idx_user_name (user_name) USING GIN("parser" = "none");
* 용도: WHERE user_name = 'rocky', WHERE user_name IN ('a', 'b') 등의 쿼리 가속.
2. 긴 문장 내 키워드 검색용 (Full-text Search)
로그 메시지나 게시글 내용처럼 긴 문자열에서 특정 단어를 찾고 싶을 때 사용합니다.
sql
-- 'logs' 테이블의 'message' 컬럼에 단어 단위 인덱스 추가
ALTER TABLE logs
ADD INDEX idx_message (message) USING GIN("parser" = "english");
* 용도: WHERE message MATCH 'error' 처럼 특정 단어가 포함되었는지 찾는 쿼리 가속.
──────────
주의사항 및 팁
1. 동작 방식: ALTER TABLE 명령어를 실행하면 백그라운드에서 기존 데이터에 대해 인덱스 생성 작업이 시작됩니다.
2. 진행 상태 확인: 인덱스가 잘 생성되고 있는지 아래 명령어로 확인할 수 있습니다.
sql
SHOW ALTER TABLE COLUMN;
(State가 `FINISHED`가 되면 인덱스가 완전히 적용된 것입니다.)
3. 삭제 방법: 만약 인덱스를 지우고 싶다면 다음 명령어를 사용합니다.
sql
ALTER TABLE users DROP INDEX idx_user_name;
참고: Inverted Index는 StarRocks *3.3 버전 이상*부터 정식 지원하므로, 사용 중인 버전을 꼭 확인해 보세요. (SELECT VERSION();)
References
• table_design/indexes/inverted_index.md
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_INDEX.mdSangwon
07/15/2026, 6:33 AMRocky
07/15/2026, 6:33 AM=, !=, >, >=, <, <=, IN 연산에 대해 검색 성능을 높여줍니다.
* LIKE 검색의 경우, `LIKE 'abc%'`와 같은 전방 일치 검색에서도 성능 향상을 기대할 수 있습니다.
──────────
다른 설정과의 비교
설정값 | 처리 방식 | 적합한 용도
"parser" = "none" | 원문 그대로 저장 | ID, 사용자 이름, 상태 코드 등 정확한 값 비교
"parser" = "english" | 영어 단어 단위로 쪼개서 저장 | 로그 메시지, 설명글 등 영어 키워드 검색
"parser" = "chinese" | 중국어 형태소 분석 후 저장 | 중국어 텍스트 검색
왜 사용하나요?
StarRocks에서 `ORDER BY`에 포함되지 않은 컬럼으로 WHERE column = 'value' 조회를 하면 전체 데이터를 다 뒤져야 할 수도 있습니다(Full Scan). 이때 `"parser" = "none"`으로 인덱스를 걸어두면, 테이블 전체를 읽지 않고 인덱스를 통해 해당 데이터가 있는 위치만 콕 집어낼 수 있어 조회 속도가 매우 빨라집니다.
한 줄 요약: MySQL에서 컬럼에 그냥 `INDEX`를 거는 것과 가장 유사한 동작을 하게 만드는 옵션입니다.
References
• table_design/indexes/inverted_index.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_INDEX.mdSangwon
07/15/2026, 7:06 AMRocky
07/15/2026, 7:06 AMORDER BY
만약 MySQL의 복합 인덱스처럼 *순서가 성능에 결정적인 영향*을 주는 것을 찾으신다면, 그것은 테이블 생성 시 지정하는 ORDER BY (Sort Key) 절입니다.
* `ORDER BY (A, B, C)`: A가 가장 먼저 필터링에 사용되며, A 조건 없이 B나 C로만 조회하면 인덱스(Prefix Index) 효과를 제대로 보지 못합니다. (MySQL의 가장 왼쪽 접두사 원칙과 유사)
3. Bloom Filter 사용 시 진짜 중요한 것
순서보다는 아래의 *데이터 특성*을 고려하는 것이 훨씬 중요합니다.
* 고유값(Cardinality)이 높은 컬럼: ID, 주민번호, 이메일처럼 값이 아주 다양한 컬럼에 걸어야 효과가 좋습니다. (성별처럼 값이 몇 개 없는 곳에는 비효율적)
* = 또는 IN 조건: Bloom Filter는 오직 column = 1 또는 column IN (1, 2, 3) 같은 조건에서만 작동합니다. (범위 조회 > 나 < 에는 작동하지 않음)
* 제외 대상: 해당 컬럼이 이미 ORDER BY 절의 앞부분에 포함되어 있다면, 이미 Prefix Index가 역할을 하고 있으므로 굳이 Bloom Filter를 또 걸 필요는 없습니다.
요약
* `bloom_filter_columns`의 순서는 상관없다. (각 컬럼별로 따로 생성됨)
* 복합 인덱스 같은 효과를 내려면 ORDER BY 절의 컬럼 순서에 신경 써야 한다.
* Bloom Filter는 *ID성 컬럼*의 = 조회 성능을 높이는 데 특화되어 있다.
References
• table_design/indexes/Bloomfilter_index.md
• best_practices/query_tuning/schema_tuning.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
References
• knowledge/usage/best-practice.md
• table_design/indexes/Bloomfilter_index.md
• best_practices/query_tuning/schema_tuning.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.mdSangwon
07/15/2026, 7:14 AMRocky
07/15/2026, 7:14 AMVARCHAR 모두 가변 길이(Variable-length) 타입입니다.
* 예를 들어, `VARCHAR(100)`과 STRING 컬럼에 똑같이 "Rocky"라는 5글자를 저장하면, 디스크에 차지하는 물리적인 저장 공간은 동일합니다.
2. 쿼리 성능 및 메모리 (Performance & Memory) - 차이 있음
* 메모리 예약(Pre-allocation): StarRocks의 일부 쿼리 실행 연산자(예: 조인, 집계 등)는 데이터를 처리하기 위해 메모리를 미리 할당합니다. 이때 실제 데이터의 길이가 아닌 *선언된 컬럼의 최대 길이*를 기준으로 메모리를 예약하는 경우가 있습니다.
* `STRING`은 내부적으로 `VARCHAR(65533)`과 유사하게 취급됩니다. 따라서 `VARCHAR(20)`으로 충분한 컬럼을 `STRING`으로 설정하면, 시스템이 불필요하게 큰 메모리를 예약하게 되어 메모리 낭비가 발생하고 전체적인 쿼리 병렬 처리 능력이 떨어질 수 있습니다.
3. 프리픽스 인덱스 (Prefix Index) 영향
* StarRocks는 테이블의 앞부분 컬럼들을 조합해 36바이트의 *프리픽스 인덱스*를 생성합니다.
* `VARCHAR`나 STRING 컬럼이 테이블 정의의 중간에 있으면 인덱스가 거기서 끊길 수 있습니다. 길이를 명확히 제한하면 인덱스 효율을 설계할 때 더 예측 가능해집니다.
──────────
요약 및 권장사항
1. 가장 좋은 방법: 실제 들어올 데이터의 최대 길이를 예상하여 *`VARCHAR(N)`*을 사용하세요. (예: VARCHAR(50))
2. `STRING`을 쓰는 경우: 데이터의 길이를 도저히 가늠할 수 없거나, 65,533바이트를 초과하는 매우 긴 텍스트를 저장해야 할 때만 사용하세요.
3. 주의사항: StarRocks의 `VARCHAR(N)`에서 *`N`은 '글자 수'가 아니라 '바이트(Byte) 수'*입니다. 한글은 보통 한 글자에 3바이트를 차지하므로, 한글 10글자를 저장하려면 최소 VARCHAR(30) 이상으로 설정해야 합니다.
한 줄 결론: 디스크 용량은 같지만, *메모리 효율과 쿼리 속도*를 위해 `VARCHAR(N)`으로 길이를 지정해주는 것이 좋습니다.
References
• faq/table_design_faq.md
• sql-reference/data-types/string-type/VARCHAR.md
• faq/Sql_faq.md
• faq/Others.md
References
• knowledge/usage/best-practice.md
• faq/table_design_faq.md
• faq/Others.md
• sql-reference/data-types/string-type/VARCHAR.md
• faq/Sql_faq.md
• best_practices/query_tuning/schema_tuning.md