select distinct
concat(sido,' ',gugun,' ',prov,' ',sigungubldnm) address2,
postno
from fms_postinfo a
where concat(prov,bunji) like concat('%',replace('내수동', ' ', ''),'%')
위의 쿼리를 실행하는데 속도가 너무 느리네요.. 어떻게 해야 할까요. 도와주세요
참고로 fms_postinfo에 prov, bunji, ho 로 인덱스가 생성되어 있습니다.
추가적으로 like "%str", "%str% 즉, 문자열 앞에 %조건으로 검색 할 경우
해당 Column에 INDEX가 걸려 있다 할지라도 사용되지 않습니다 이말이 맞습니다. (아래 실행 계획 참조)
이유에 대해서는 B-Tree indexes 는 substrings 를 서치 하지 못한다고 하네요
다만 속도에 문제가 있을 경우 FULLTEXT 인덱스나 , apache solr , sphinx search 같은 걸 이용해 보시는게 좋을것 같습니다.
FULLTEXT InnoDB 는 mysql 5.6 부터 지원합니다.
explain select * from film where title like 'ACE%' ;
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | film | range | idx_title | idx_title | 767 | 1 | 100 | Using index condition |
explain select * from film where title like '%ACE%' ;
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | film | ALL | 1000 | 11.11 | Using where |
확인 해보니 마농님의 말이 맞습니다.
해당 조건컬럼만 을 select 한 경우에 index를 full scan 했으며, 해당 조건 컬럼외 다른 컬럼등을
조회 했을경우는 index scan을 하지 않고 table full 스캔을 수행했습니다.
단 select film_id,title from film where title like '%ACE%' ; <= 이것 처럼 프라이머리 키(film_id) 같이
select 한 경우는 index scan을 합니다.
mysql> select title from film where title like '%ACE%' ;
mysql> select film_id,title from film where title like '%ACE%'
mysql> show status like 'han%' ;
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_commit | 1 |
| Handler_delete | 0 |
| Handler_discover | 0 |
| Handler_external_lock | 2 |
| Handler_mrr_init | 0 |
| Handler_prepare | 0 |
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 1000 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
| Handler_rollback | 0 |
| Handler_savepoint | 0 |
| Handler_savepoint_rollback | 0 |
| Handler_update | 0 |
| Handler_write | 0 |
+----------------------------+-------+
18 rows in set (0.00 sec)
mysql> select description,title from film where title like '%ACE%' ;
mysql> select film_id,description,title from film where title like '%ACE%' ;
mysql> show status like 'han%' ;
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Handler_commit | 1 |
| Handler_delete | 0 |
| Handler_discover | 0 |
| Handler_external_lock | 2 |
| Handler_mrr_init | 0 |
| Handler_prepare | 0 |
| Handler_read_first | 1 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 1001 |
| Handler_rollback | 0 |
| Handler_savepoint | 0 |
| Handler_savepoint_rollback | 0 |
| Handler_update | 0 |
| Handler_write | 0 |
+----------------------------+-------+