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
운영게시판
최근게시물
DB2 Q&A 1671 게시물 읽기
No. 1671
다시 view에 대해 질문드립니다.
작성자
이도희
작성일
2008-07-03 18:30
조회수
10,298

냥이 님의 말씀대로 테이블에 대한 뷰를 생성하고 한 row를 검색했을 때는 full scan을 하지 않고, index도 타는 것을 토드를 통해 확인했습니다.


하지만 이상한것은 제가 테스트 한 게


db2 "create table jodeng2.performance_test( id integer not null, name varchar(30) )"

db2 "begin atomic                         

  declare idx integer default 0;

  declare total_row integer default 100;

  while ( idx < 100 ) do

    insert into jodeng2.performance_test values ( idx, 'name:' || char(idx) );

    set idx = idx + 1;                                                          

  end while;

end"

이렇게 해서 테이블을 생성하고,

create index jodeng2.idx_test on jodeng2.performance_test(id);


파일로 쓰는 dll을 호출하는 함수를 생성

#include <stdlib.h>

#include <sqlcli1.h>

#include <sqludf.h>

#include <stdio.h>

#include <string.h>

void writefile(char *name, char *out, int name_ind, int out_ind, SQLUDF_TRAIL_ARGS )

 {

   FILE *fp = fopen("/tmp/test","a");

   if (fp == NULL )

   {

     strcpy( out, "error" ); return;

   }

  fprintf(fp,"%s\n", name);

  strcpy(out, name);

  fclose(fp);

}


drop function test_func;

CREATE FUNCTION  test_func ( VARCHAR(30) )

returns varchar(30)

EXTERNAL NAME 'libwrite.so!writefile'

LANGUAGE C

PARAMETER STYLE DB2SQL

DETERMINISTIC

reads sql data

 EXTERNAL ACTION;

이렇게 사용자 정의 함수를 만들고 view에서는

create view jodeng2.test_view(id, name)  as select id, jodeng2.test_func(name) name from jodeng2.performance_test 이렇게 만듭니다.

그리고 뷰를 select 하게 되면

select id from jodeng2.test_view where id=3 이라고 한 행만 select하게 되어도

토드에서 쿼리 플랜을 확인해보면 테이블에서 index를 타지 않고 모든 row를 스캔하는 것을 볼 수 있습니다.

뷰가 bulit-in함수를 타는 경우는 index를 타는데 사용자 정의 함수를 타게 되면 index를 타지 않고 full scan 하게 됩니다.

이를 피할 수 있는 방법이 없을까요? 가령 함수에 어떤 옵션을 준다거나 하는 거요.

해결 방법을 모르겠습니다.

이렇게 되면 테이블에 100만건이 있는데 뷰에서 한 행만 검색하는데도 100만 row를 다 스캔하는건데 .. 해결 방법이 없나요?

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


테스트를 해봐야 하겠지만 index를 제대로 선택하지 못하는 케이스가 하나더 나온거 같네요. ㅎㅎ 

이런경우 user temp table을 사용해보세요. 


declare global temporary table gt1 as 
(select id, jodeng2.name name from odeng2.performance_test) definition only 
on commit preserve rows not logged ;

insert into session.gt1 select id, jodeng2.name name from odeng2.performance_test where id=3;
select id, jodeng2.test_func(name) name from session.gt1;

조는 냥이님이 2008-07-04 09:30에 작성한 댓글입니다.
이 댓글은 2008-07-04 09:36에 마지막으로 수정되었습니다. Edit

인덱스를 타고 안타는 것은 db2는 8버전 까지 전적으로 Optimizer에 의해 결정됐습니다.
다시말해서 Optimizer가 결정하는 데이터가 정확하지 않으면 인덱스를 타야함에도 불구하고
타지 않는 경우가 있습니다.
보통은 테이블에 iud 작업을 하시고 runstat 또는 reorg 작업을 하지 않아 발생하는 경우가 대부분이고요
통계정보가 정확하다면 왠만한 튜너보다 실행계획이 더 잘나온다고 볼수 있습니다.
주요테이블에 대해서 주기적으로 통계정보 runstat 및 roerg 작업을 해주시면 쿼리성능 향상에 많은 도움이 되지 않을까 싶습니다.

간단한 저의 소견이었습니다.
건승하세요

구광모(kkm0802)님이 2008-07-29 13:22에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
1674사용자 그룹에 대해서 질문드립니다. [2]
이도희
2008-07-08
9785
1673안녕하세요 insert에 대해서 물어볼려고 합니다. [4]
방효현
2008-07-07
11096
1672create function 문의 external action [1]
이도희
2008-07-04
9631
1671다시 view에 대해 질문드립니다. [2]
이도희
2008-07-03
10298
1670view에 대해 질문드립니다. [3]
이도희
2008-07-03
9795
1669instead of 트리거 생성시 에러가 납니다.
이도희
2008-07-02
9729
1668결과값이 없을때 특정 select 실행법 [2]
윤동민
2008-07-02
10304
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2021 DSN, All rights reserved.
작업시간: 0.011초, 이곳 서비스는
	PostgreSQL v13.3으로 자료를 관리합니다