MYSQL 속도 개선할 수 있게 도와주세요 0 8 7,653

by 불장작 [2016.02.25 11:26:30]


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 로 인덱스가 생성되어 있습니다.

 

by 겸댕2후니 [2016.02.25 13:28:33]

조건절 컬럼에 함수가쓰이면, FBI(Function based index)를 사용하지 않는 한

인덱스를 제대로 사용할 수 없습니다.

proj와 bunji를 각각 분리하여 조건을 주시기 바랍니다.


by 불장작 [2016.02.25 15:38:17]

답변 감사합니다.

그런데 어떻게 해야 하는지 구체적인 방법을 알려주실수는 없나요?

mysql 초보라서


by DeSSa [2016.02.25 15:38:31]

추가적으로 like "%str", "%str% 즉, 문자열 앞에 %조건으로 검색 할 경우

해당 Column에 INDEX가 걸려 있다 할지라도 사용되지 않습니다.

 

※테이블 구조와 자신이 하려고 하는 트랜잭션에 대해 알아야 다른분들께서 가이드 드리기가

더 수월 할것 같습니다.


by 불장작 [2016.02.25 15:53:21]

답변 너무너무 감사합니다.


by 마농 [2016.02.25 16:08:39]

CONCAT 함수가 사용되었고, LIKE 검색시 '%' 가 앞에 사용되었어도
인덱스 범위 검색은 불가능하지만 인덱스 풀스캔은 가능은 합니다.
일단 실행계획부터 확인해 보세요.


by l2monkeys [2016.02.29 12:04:59]

추가적으로 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


by 마농 [2016.02.29 17:14:54]

컬럼을 가공했을 때 인덱스를 이용할수 없는 가능성이 커지는 것은 맞습니다.
그러나 100% 인덱스를 사용하지 못한다고 단정지어 말할 수는 없습니다.
인덱스 레인지 스캔은 할 수 없을 지는 몰라도.
인덱스 풀스캔을 이용 할 수도 있기 때문입니다.


by l2monkeys [2016.03.02 12:22:57]

확인 해보니 마농님의 말이 맞습니다.

해당 조건컬럼만 을 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     |
+----------------------------+-------+

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입