database.sarang.net
UserID
Passwd
Database
DBMS
ㆍMySQL
PostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
MySQL Q&A 27523 게시물 읽기
No. 27523
mysql5 에서 view 테이블 속도 관련해서 문의드립니다.
작성자
유영재
작성일
2008-04-17 14:11
조회수
11,338

mysql5 버전에서 view 테이블을 구성하고 select를 수행할 경우 속도가 너무 느려 이렇게 질문을 드립니다.

일반적인 view의 경우는 아무런 문제가 되지 않습니다만..

create ALGORITHM=merge view bd_contents_view as
select
cm_domain_key as dc_domainkey,
bs_search_all as dc_search_all,
bs_search_type as dc_search_type,
bs_search_none as dc_search_none,
bs_catelist as dc_catelist,
bs_fullcate as dc_fullcate,
ct_dir as dc_dir,
ct_bid as dc_bid,
ct_hid as dc_hid,
ct_idx as dc_cid,
abs(ct_group) as dc_group,
ct_order as dc_order,
ct_subject as dc_subject,
concat_ws(',.,:', ct_content, (select GROUP_CONCAT(cmt_content SEPARATOR ',.,:') from comment use index (list) where cmt_cid=ct_idx)) as dc_content,
ct_tags as dc_tags,
DATE_FORMAT(ct_reg_date, '%Y%m%d%H%i%s') as dc_regdate,
ct_x as dc_x,
ct_y as dc_y,
ct_delete as dc_delete,
ct_penname as dc_penname,
ct_ext_field as dc_ext,
ct_uid as dc_uid,
ct_img as dc_img
from contents use index (PRIMARY)
left join board use index (PRIMARY) on (ct_bid = bs_idx)
left join community use index (PRIMARY) on (bs_cid = cm_idx)
where ct_idx>0 and bs_search_none != 'all' and (bs_search_type like "bd%" or bs_search_type like "fore%") and ct_delete="n";

위와같이 view를 생성할 경우 엄청난 속도 저하가 발생합니다. 

쿼리를 보시면 서브쿼리등의 문제로 속도가 빠르면 이상하지 않은가? 하고 생각 하시는 분들이 있으리라 생각됩니다만... ㅋ

문제는 view로 구성하지 않고 아래와 같이 동일하게 select는 속도가 느리지 않습니다.

select
cm_domain_key as dc_domainkey,
bs_search_all as dc_search_all,
bs_search_type as dc_search_type,
bs_search_none as dc_search_none,
bs_catelist as dc_catelist,
bs_fullcate as dc_fullcate,
ct_dir as dc_dir,
ct_bid as dc_bid,
ct_hid as dc_hid,
ct_idx as dc_cid,
abs(ct_group) as dc_group,
ct_order as dc_order,
ct_subject as dc_subject,
concat_ws(',.,:', ct_content, (select GROUP_CONCAT(cmt_content SEPARATOR ',.,:') from comment use index (list) where cmt_cid=ct_idx)) as dc_content,
ct_tags as dc_tags,
DATE_FORMAT(ct_reg_date, '%Y%m%d%H%i%s') as dc_regdate,
ct_x as dc_x,
ct_y as dc_y,
ct_delete as dc_delete,
ct_penname as dc_penname,
ct_ext_field as dc_ext,
ct_uid as dc_uid,
ct_img as dc_img
from contents use index (PRIMARY)
left join board use index (PRIMARY) on (ct_bid = bs_idx)
left join community use index (PRIMARY) on (bs_cid = cm_idx)
where ct_idx>0 and bs_search_none != 'all' and (bs_search_type like "bd%" or bs_search_type like "fore%") and ct_delete="n";

동일한 쿼리를 view로 구성해서 select 한것과 그냥 select 한 것이 왜 차이가 나는지 모르겠네요.. ㅋ


mysql> explain select * from bd_contents_view;
+----+--------------------+------------+--------+---------------+---------+---------+---------------------+------+-------------+
| id | select_type        | table      | type   | possible_keys | key     | key_len | ref                 | rows | Extra       |
+----+--------------------+------------+--------+---------------+---------+---------+---------------------+------+-------------+
|  1 | PRIMARY            | <derived2> | ALL    | NULL          | NULL    | NULL    | NULL                | 1431 |             |
|  2 | DERIVED            | contents   | range  | PRIMARY,list  | PRIMARY | 4       | NULL                |  533 | Using where |
|  2 | DERIVED            | board      | eq_ref | PRIMARY       | PRIMARY | 4       | sem.contents.ct_bid |    1 | Using where |
|  2 | DERIVED            | community  | eq_ref | PRIMARY       | PRIMARY | 4       | sem.board.bs_cid    |    1 |             |
|  3 | DEPENDENT SUBQUERY | comment    | ref    | list          | list    | 4       | sem.contents.ct_idx |    1 |             |
+----+--------------------+------------+--------+---------------+---------+---------+---------------------+------+-------------+

mysql> explain select cm_domain_key as dc_domainkey, bs_search_all as dc_search_all, bs_search_type as dc_search_type, bs_search_none as dc_search_none, bs_catelist as dc_catelist, bs_fullcate as dc_fullcate, ct_dir as dc_dir, ct_bid as dc_bid, ct_hid as dc_hid, ct_idx as dc_cid, abs(ct_group) as dc_group, ct_order as dc_order, ct_subject as dc_subject, concat_ws(',.,:', ct_content, (select GROUP_CONCAT(cmt_content SEPARATOR ',.,:') from comment use index (list) where cmt_cid=ct_idx)) as dc_content, ct_tags as dc_tags, DATE_FORMAT(ct_reg_date, '%Y%m%d%H%i%s') as dc_regdate, ct_x as dc_x, ct_y as dc_y, ct_delete as dc_delete, ct_penname as dc_penname, ct_ext_field as dc_ext, ct_uid as dc_uid, ct_img as dc_img from contents use index (PRIMARY) left join board use index (PRIMARY) on (ct_bid = bs_idx) left join community use index (PRIMARY) on (bs_cid = cm_idx) where ct_idx>0 and bs_search_none != 'all' and (bs_search_type like "bd%" or bs_search_type like "fore%") and ct_delete="n";
+----+--------------------+-----------+--------+---------------+---------+---------+---------------------+-------+-------------+
| id | select_type        | table     | type   | possible_keys | key     | key_len | ref                 | rows  | Extra       |
+----+--------------------+-----------+--------+---------------+---------+---------+---------------------+-------+-------------+
|  1 | PRIMARY            | contents  | range  | PRIMARY       | PRIMARY | 4       | NULL                | 64725 | Using where |
|  1 | PRIMARY            | board     | eq_ref | PRIMARY       | PRIMARY | 4       | sem.contents.ct_bid |     1 | Using where |
|  1 | PRIMARY            | community | eq_ref | PRIMARY       | PRIMARY | 4       | sem.board.bs_cid    |     1 |             |
|  2 | DEPENDENT SUBQUERY | comment   | ref    | list          | list    | 4       | sem.contents.ct_idx |     1 |             |
+----+--------------------+-----------+--------+---------------+---------+---------+---------------------+-------+-------------+


두개의 explain 결과의 차이를 보면 view로 구성 후엔 DERIVED가 나타나면서 파생되었다고 알려주는데.. 이게 원인인 듯합니다만...

이 부분을 어떻게 하면 해결할 수 있을까요?

view의 ALGORITHM 도 변경을 해봤으나 소용이 없었습니다. ㅜㅜ

중간에 서브쿼리를 제거하면 해결이 되긴합니다만... 이해할 수 없는 것은 동일한 쿼리를 view로 구성했을 뿐인데 이렇게 차이가 나는 이유입니다.

google에서 검색을 해봐도 해결안은 보이질 않네요..

혹시 관련 내용을 아시는 분이 계시면 조그만 조언이라도 알려주시면 감사하겠습니다. ^^;

이 글에 대한 댓글이 총 1건 있습니다.

답변이 없어 포기하고 지내다 다시 이런 경우가 생겨 구글에 검색을 해보았습니다. 

역시나 이 문제를 고민하는 분들이 있는데.. 해결안이 없더군요.. 단지 mysql view 사용시엔 이런경우를 조심해야 한다고 ㅡㅡ;

그러던 중 새로운 방법이 생각나서 해보니 훨씬 나은 성능이 나와 이렇게 시간이 지났음에서 댓글을 달아 둡니다. ㅋ

현 문제는 view 테이블 안에서의 서브쿼리 문제 였습니다.  동일한 쿼리 임에도 불구하고 view로 만들기만 하면 파생테이블이 생겨버리는 문제가.. 구글에선 mysql 의 버그다.. 라고 얘기하시는 분들도 계시더군요.. ㅋ

여기서 생각난것이 스토어드함수 입니다. 서브쿼리 부분을 스토어드 함수로 분리하고 그 함수를 불러 서브쿼리 결과를 받으면 괜찮지 않을까? ㅋ

결론은 파생테이블이 생기지 않았습니다. ㅋ
당연히 그냥 쿼리를 날렸을때와 view로 만들었을때의 속도는 동일하게 나오더군요..

왜 진작에 스토어드 함수를 생각해 보지 못했는지.. ㅋㅋ 사실 최근에서야 스토어드함수와 프로시저를 사용하고 있으니 예전엔 생각못했던 것도 당연한건지.. ㅋ

어쨌든 비슷한 상황에 있으신 분들은 스토어드 함수의 사용을 고려해보세요. ㅋ

깗은 제 경험상 스토어드함수나 프로시저를 잘 사용하면 무지하게 편해지는 부분들이 많더군요.. 데이터 무결성을 보장하기 위해서 사용할 수도 있고(트렌젝션을 지원할 경우).. ㅋ

유영재님이 2008-09-24 10:31에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
27526mysql cluster를 설치해서 테스트중입니다. [1]
조원국
2008-04-18
4145
27525MySQL strict Mode 해제방법이 궁금합니다. [3]
김전일
2008-04-18
3882
27524datetime 필드에 default value 로 now() 값을 집어넣을 수 없나요? [2]
김종화
2008-04-17
8536
27523mysql5 에서 view 테이블 속도 관련해서 문의드립니다. [1]
유영재
2008-04-17
11338
27522MS-SQL과 연결된 서버 설정 후 데이터 누락문제
이기성
2008-04-17
3663
27518apmsetup5와 자바가 연동이 안됩니다....;;
유재훈
2008-04-16
3140
27517트리거가...이상해여...어찌..
서용욱
2008-04-16
2936
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다