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 로 인덱스가 생성되어 있습니다.
조건절 컬럼에 함수가쓰이면, FBI(Function based index)를 사용하지 않는 한
인덱스를 제대로 사용할 수 없습니다.
proj와 bunji를 각각 분리하여 조건을 주시기 바랍니다.
답변 감사합니다.
그런데 어떻게 해야 하는지 구체적인 방법을 알려주실수는 없나요?
mysql 초보라서
추가적으로 like "%str", "%str% 즉, 문자열 앞에 %조건으로 검색 할 경우
해당 Column에 INDEX가 걸려 있다 할지라도 사용되지 않습니다.
※테이블 구조와 자신이 하려고 하는 트랜잭션에 대해 알아야 다른분들께서 가이드 드리기가
더 수월 할것 같습니다.
답변 너무너무 감사합니다.
CONCAT 함수가 사용되었고, LIKE 검색시 '%' 가 앞에 사용되었어도
인덱스 범위 검색은 불가능하지만 인덱스 풀스캔은 가능은 합니다.
일단 실행계획부터 확인해 보세요.
추가적으로 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 |
컬럼을 가공했을 때 인덱스를 이용할수 없는 가능성이 커지는 것은 맞습니다.
그러나 100% 인덱스를 사용하지 못한다고 단정지어 말할 수는 없습니다.
인덱스 레인지 스캔은 할 수 없을 지는 몰라도.
인덱스 풀스캔을 이용 할 수도 있기 때문입니다.
확인 해보니 마농님의 말이 맞습니다.
해당 조건컬럼만 을 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 |
+----------------------------+-------+