/*+ FIRST_ROWS */ 기능을 0 10 2,761

by 최원석 [2008.12.19 09:11:42]


init.ora (2,598Bytes)

유닉스용 오라클 9i 사용중이며

start with를 하면서 다른 테이블과 조인을 맺으면서

BOM 전개하니 시간이 너무 많이 걸려서 포기하고 있었는데

여기를 통해서 인덱스를 사용한 시간 절약 가능한 기능을 알게되었습니다.

 select /*+ FIRST_ROWS */a.ccode_item,
        b.code_item_name,
    b.item_size,
    b.unit,
    c.car_name
   from biz01.tbl_bom a,
        biz01.tbl_itemcode b,
        biz01.tbl_goods_car_kind c
  where a.ccode_item = b.code_item
    and b.car_code = c.car_code (+)
      and b.item_kind <> 'I'
  start with a.pcode_item = 'AB1D610007'
    and '20081218' between a.s_date and a.e_date
  connect by prior a.ccode_item = a.pcode_item
    and '20081218' between a.s_date and a.e_date
    and prior b.jodal_code not in ( '11', '12', '51', '52' );

머 이렇게 하면 효과가 있더군요. 이런 것을 튜닝이라고 하는 것 같은데.

제가 파워빌더로 개발하는데 파워빌더에서는 /* */ 가 주석 처리하도록 해서 그런지

스크립트 안에 넣고 실행하면 /*+ FIRST_ROWS */ 가 제대로 동작하지 않는 것 같습니다.

생각을 잘 못 하고 있는지 모르겠지만, 이 기능(실행계획?)을 DB자체에 설정으로 넣어 주고 싶습니다.

init.ora는 첨부파일에 넣어 두었으니 봐주십시요.

어떤 것을 어떻게 설정해야 full scan이 아닌 index 위주의 쿼리로 실행되도록 할 수 있을까요?

by 호야 [2008.12.19 09:34:36]
어차피 SQL 문을 파워빌더에 넣을 때
" SELECT /*+ 힌트절 */ 컬럼들 ~ FROM 테이블 "
이런 쌍 따움표를 사용하지 않나요?
안된다면..-_- 파워 빌더는 몰것는데...
상위 힌트는 옵티마이저 모드에 관한 제어 힌트 입니다.
RULE 방식의 모드는 사용자가 옵티마이저 관점에서 인덱스 활용에
대한것을 다 생각해서 만들어야지 규칙에 의해 돌아 가지만,
FIRST_ROWS는 옵티마이저에게 권한을 넘긴다고 보면 쉽습니다.
말을 길게 쓰는 최적의 응답시간을 목표로 초지ㅓ 비용의 실행계획을
수립하도록 유도를 하는 것이구요

저렇게 좋은 방식이 있는 모드 자체를 안 바꾸시는 이유는 FIRST_ROWS
는 어디로 튈지 모릅니다. 그?? 그때 옵티마이저가 테이블의 통계를 보고
판단을 하기 때문이죠

쉽사리 오라클 파라미터를 고치라고는 말씀 못 드리겠네요.^^:

가장 쉬운 힌트중에 하나 입니다. sql을 접근을 하는게 아니라
옵티마이저 푸는 전체 방법론을 제시 하는 것이기에
FIRST_ROWS, ALL_ROWS, RULE등 여러 힌트를 접해 보시고
좋은 실행계획이 나오는 쪽으로 사용하시는게 좋을 듯합니다.

by TeLl2 [2008.12.19 09:48:03]
9i를 사용중이라면 기본 optimizer mode가 choose일 겁니다.
choose는 통계정보가 있으면 cbo로 작동하고
없으면 rbo로 동작하게 됩니다.
말씀하시는 first_rows는 cbo모드로 작동할 경우에만 적용되게 됩니다.
init.ora파일에 옵티마이져 모드를 변경시에는 전체 데이터 베이스의
실행계획에 영향을 미치게 됩니다.
보통 oltp환경에서는 first_rows 혹은 first_rows_n 로 설정을 하게 사용하는데요.
운영환경에서의 테스트 없이 모드를 변경하는 것은 권장되지 않습니다.
테스트 환경 구축 후 영향도를 파악하셔서 적용하셔야 합니다.
특정 sql만을 위한 것이라면 위와 같이 힌트를 적용하셔서 처리하시는것이
바람직 합니다.
초기화 파라미터 변경은
optimizer_mode=FIRST_ROWS
위의 값을 추가 혹은 있다면 위와 같이 변경하시면 됩니다.

by 최원석 [2008.12.19 10:02:34]
호야님 FIRST_ROWS가 가장 빠르게 실행되는 것으로 나왔습니다.

by 호야 [2008.12.19 10:14:19]
전체적 부하 테스트가 없기 ??문에.. 앞으로 테스팅을 통해서 바꾸도록
하세요.^^: 그리고 9i 이하 버전들은 통계정보 생성이 드문 드문 되어있나
한번 보시구요. 어떤 테이블은 통계정보가 되어 있고 어떤 테이블은 안되어
있으면 9i는 맛이 가버립니다.-_-
아예 다 지우고 사용자 index 위주로 가실건지...
전부 통계를 만들어서 DBMS 한테 위임을 하시든지요.ㅎ
앞으로 SQL 을 짜면서 계속적인 FIRST_ROWS n 만 필요 하다면
이미 만들어진 SQL들에 적용을 해 보시고 나중에 모드를 바꾸시는
것두 좋은 방법일듯합니다.

by 마농 [2008.12.19 10:27:23]
혹시나 해서 답글 달아봅니다. 이런식의 힌트도 가능합니다.
SELECT --+ FIRST_ROWS
a.ccode_item,
...

by 최원석 [2008.12.19 10:43:48]
오 마농님 그 방식 맘에 듭니다.
다르게 테스트 해봐야 겠습니다.후다닥~

by 호야 [2008.12.19 10:55:48]
단 뒤에 이어 쓰면 전부 주석 됩니다..ㅋㅋ
select --+ 힌트절 <엔터>
컬럼명시~~~ 쭈욱..-_- 근데 이놈들은 한데 합치면 또
sql=sql+chr(13)+"~~~ 이런식으로 쓰이면 안될텐데"
씩으로 엔터를 명시를 하세요 어플에서는

by 최원석 [2008.12.19 10:57:29]
흠...파워빌더에서 마농님 표현대로 하니 에러가 나네요 ㅠ.ㅠ

by 호야 [2008.12.19 11:48:01]
에러나는 부분을 유추 하면
sql의 주석 부분을 이해 하셔야 합니다
-- 는 한줄 주석입니다
/* */ 안에 있는거 주석입니다
그렇기 ??문에 변수 하나에
STRING SQL 이라는 변수를 만들었을 경우
SQL="SELECT --+ 힌트절";
SQL=SQL+ "FROM ~ 어쩌구 저쩌구"
결론
SQL="SELECT --+ 힌트절 FROM 어쩌고";
이게 되므로 SELECT 뒤로는 전부 주석처리가 되었을 겁니다
즉... SQL="SELECT -- 힌트절+ CHR(13) 이라는 ASCII 코드로 "엔터"를
넣어 주셔야 주석처리 안되고 힌트를 쓸수 있을 겁니다.

by 현 [2008.12.22 09:13:09]
그냥 TeLl2 님 말씀대로 옵티마이져 모드를 변경해 주시면 되실듯...
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입