냥이 님의 말씀대로 테이블에 대한 뷰를 생성하고 한 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를 다 스캔하는건데 .. 해결 방법이 없나요?
|