like 사용 시 주의사항을 설명하기 앞서 문자열 인덱스에 대해서 알아보자.
문자열 인덱스
인덱스는 다양한 데이터 유형에 대해서 만들 수 있지만, 문자열 컬럼에 인덱스를 만드는 경우에 대해서 설명하겠다.
문자열 인덱스는 문자열 비교를 할 때 왼쪽에서 오른쪽으로 문자를 비교하는 방식으로 구현된다. 그렇기 때문에 특정 접두사로 시작하는 문자열을 검색할 때는 효율적인 검색이 가능하다.
문자열 인덱스는 DBMS의 종류에 따라서, 혹은 하나의 DBMS에서도 스토리지 엔진의 종류에 따라서 구현 방식이 달라질 수 있다.
주로 사용되는 구현 방식은 B-Tree, 해시이다.
B-Tree | 해시 | |
---|---|---|
최선 | O(1) 루트인 경우 | O(1) |
평균 | O(log N) | O(1) |
최악 | O(log N) | O(1) |
결국 인덱스는 O(log N) ~ O(1) 시간 내에 검색을 하게 되지만 인덱스를 사용하지 않으면 모든 row를 조회하게 되어 O(N)의 검색 시간이 소요된다.(찾으려는 데이터가 가장 마지막 row에 있을 수도 있기 때문에 모든 row를 조회함)
대용량 데이터에서 인덱스를 사용하지 않고 전체 데이터를 조회하여 검색하게 되는 경우 심각한 성능 문제를 야기할 수 있다.
DBMS 별 인덱스 구현 방식
데이터베이스 | 인덱스 구현 방식 |
---|---|
MySQL - InnoDB | B-tree (기본 인덱스) |
MySQL - MyISAM | B-tree |
MySQL - Memory | Hash (기본 인덱스), B-tree |
PostgreSQL | B-tree (기본 인덱스), Hash, GIN, GiST, SP-GiST, BRIN |
Oracle | B-tree (기본 인덱스), Bitmap, Hash |
Microsoft SQL Server | B-tree (기본 인덱스), Hash (메모리 최적화된 테이블) |
SQLite | B-tree |
MongoDB | B-tree (기본 인덱스), Geospatial, Text, Hash |
Redis | Skip List (기본 인덱스), Hash (데이터 구조에 따라 다름) |
Cassandra | SSTable (Sorted String Table), Bloom Filter (빠른 검색을 위해) |
Elasticsearch | Inverted Index (기본 인덱스), BKD tree (숫자 및 위치 데이터) |
Apache HBase | LSM Tree (Log-Structured Merge Tree) |
like 문
컬럼의 문자열을 비교할 때 like 문을 사용해서 비교하게 된다.
패턴 문자열이라는 것을 사용해서 비교를 하게 되는데 주로 사용하는 기호들은 다음과 같다.
%
기호는 해당 자리에 0글자 이상의 랜덤 문자가 올 수 있다는 것을 의미하고,_
기호는 해당 자리에 1글자의 랜덤 문자가 올 수 있다는 것을 의미한다.
like 성능 문제
하지만 like를 사용할 때 주의할 점이 있다.
바로 %
나 _
가 패턴 문자열의 가장 앞에 오는 경우에 성능에 나쁜 영향을 끼치게 된다는 것이다.
앞서 말했듯 인덱스는 접두사를 사용한 검색에서만 사용이 가능하다. 그렇기 때문에 접미사에 대해 검색하게 되면 인덱스가 존재하더라도 인덱스를 사용하지 않고 전체 검색을 하게 된다.
%
가 _
가 맨 뒤에 오는 경우는 접두사를 검색하는 경우로, 인덱스를 사용해 조회가 가능하기 때문에 성능 저하 문제가 없다.
결론
like 검색 시 %
, _
가 패턴 문자열의 가장 앞에 오게 되는 (접미사 검색) 쿼리를 날리지 말자.
'DB' 카테고리의 다른 글
인덱스 (0) | 2024.08.25 |
---|---|
전체 데이터 삭제 DELETE vs TRUNCATE (0) | 2024.08.25 |
SQL 정리 (0) | 2024.08.25 |
DB 개념 6편 - ER 모델 (0) | 2024.08.25 |
DB 개념 5편 - View와 MView의 차이 (0) | 2024.08.25 |