Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL LIKE 검색에서 와일드카드(%) 위치가 성능을 좌우하는 이유

선행 와일드카드는 MySQL 검색 성능을 향상시키지 못합니다

결론부터 말씀드리면, 아니요. LIKE 조건에서 와일드카드(%)가 문자열 앞쪽에 위치하는 패턴(예: '%John')을 사용하면 MySQL은 해당 컬럼에 설정된 인덱스를 활용할 수 없습니다. 인덱스는 기본적으로 값의 앞부분부터 정렬된 구조(B-Tree)이기 때문에, 시작 부분을 알 수 없는 선행 와일드카드 검색은 결국 테이블 전체를 스캔하는 풀 스캔(Full Table Scan)으로 이어져 성능이 크게 저하됩니다.

반면 와일드카드가 문자열 뒤쪽에 오는 후행 와일드카드 패턴(예: 'John%')이라면 인덱스를 정상적으로 사용할 수 있어 검색 속도가 크게 개선됩니다.

권장 문법: 후행 와일드카드

SELECT * FROM yourTableName WHERE yourColumnName LIKE 'anyLetter%';

예제 1. 테스트용 테이블 생성

먼저 실습에 사용할 테이블을 생성합니다.

mysql> create table TrailingWildCardDemo
   -> (
   -> Id int NOT NULL AUTO_INCREMENT,
   -> Name Varchar(20),
   -> PRIMARY KEY(Id)
   -> );
Query OK, 0 rows affected (0.71 sec)

예제 2. 샘플 데이터 삽입

INSERT 명령으로 여러 개의 레코드를 추가합니다.

mysql> insert into TrailingWildCardDemo(Name) values('John');
Query OK, 1 row affected (0.13 sec)
mysql> insert into TrailingWildCardDemo(Name) values('Johnson');
Query OK, 1 row affected (0.17 sec)
mysql> insert into TrailingWildCardDemo(Name) values('Mike');
Query OK, 1 row affected (0.16 sec)
mysql> insert into TrailingWildCardDemo(Name) values('Kevin');
Query OK, 1 row affected (0.23 sec)
mysql> insert into TrailingWildCardDemo(Name) values('Adam');
Query OK, 1 row affected (0.20 sec)
mysql> insert into TrailingWildCardDemo(Name) values('Ethan');
Query OK, 1 row affected (0.16 sec)
mysql> insert into TrailingWildCardDemo(Name) values('James');
Query OK, 1 row affected (0.19 sec)

예제 3. 저장된 전체 데이터 확인

SELECT 문으로 테이블의 모든 레코드를 조회해 보겠습니다.

mysql> select *from TrailingWildCardDemo;

실행 결과는 다음과 같습니다.

+----+---------+
| Id | Name    |
+----+---------+
|  1 | John    |
|  2 | Johnson |
|  3 | Mike    |
|  4 | Kevin   |
|  5 | Adam    |
|  6 | Ethan   |
|  7 | James   |
+----+---------+
7 rows in set (0.00 sec)

예제 4. 후행 와일드카드로 'j'로 시작하는 이름 검색

이제 후행 와일드카드를 적용한 쿼리를 실행합니다.

mysql> select *from TrailingWildCardDemo where Name LIKE 'j%';

Name 컬럼에 인덱스가 있다면 이 쿼리는 인덱스를 활용하여 빠르게 결과를 반환합니다.

+----+---------+
| Id | Name    |
+----+---------+
|  1 | John    |
|  2 | Johnson |
|  7 | James   |
+----+---------+
3 rows in set (0.00 sec)

추가 팁: 성능 확인 및 대안

실제로 인덱스가 사용되었는지 확인하려면 쿼리 앞에 EXPLAIN을 붙여 실행 계획을 살펴보세요. type 항목이 range 또는 ref로 표시되고 key 항목에 인덱스 이름이 나타나면 인덱스가 정상적으로 활용된 것입니다.

만약 부득이하게 '%문자열' 형태의 선행 와일드카드 검색이 꼭 필요하다면 다음과 같은 대안을 고려할 수 있습니다.

  • FULLTEXT 인덱스: MATCH...AGAINST 구문과 함께 사용하면 전문 검색(full-text search)으로 빠른 조회가 가능합니다.
  • 문자열 반전 기법: 접미사 검색이 필요한 경우 값을 미리 뒤집어(reversed) 저장하고, 검색 조건도 뒤집어서 후행 와일드카드 형태로 변환하면 인덱스를 활용할 수 있습니다.

정리하면, MySQL에서 LIKE 검색 성능을 최적화하려면 가급적 '접두사%' 형태의 후행 와일드카드를 사용하고, 선행 와일드카드가 불가피하다면 FULLTEXT 인덱스 등 별도의 검색 전략을 적용하는 것이 좋습니다.