2. 컴퓨터 이야기/데이타베이스 10

Unique 인덱스를 Full Scan 하는 플랜이 떠져서 확인했더니, 아차차.. ㅠ.ㅠ

역시 튜닝은 DB 모델링 시기부터 진행되어야 함을 다시 한번 뼈저리게 되새기는 기회가 되었습니다. 일단 아래 쿼리를 보시죠. (참고로 DB 클라이언트는 WareValley 사의 Orange 입니다). 두 테이블을 조인해 오는데, Hash Join 이 됩니다. 이부분은 어쩔 수 없는 부분이라 지금 이야기 하는 주제는 아닙니다. 양 테이블 모두 데이타가 천만건 단위로 쌓여 있기 때문입니다. 아래 쿼리는 두번째 테이블(b) 을 Full Scan 하기 때문에 좋은 구조는 아닙니다. 힌트를 주더라도 Full 스캔되는 것은 마찬가지 입니다. 물론 한쪽은 인덱스를 탑니다만.. 그래서 일단 exists 로 b 테이블을 내려 보내고 exists 문 안에서는 힌트를 주었습니다. 힌트는 b 테이블에 a 테이블과 조인하는 키..

오라클 Date 데이타들 간의 경과(시간차)를 일/분/초로 확인하는 방법

오라클에서 Date 형으로 된 시간들의 차이를 구할때, to_char 함수를 이용하여 문자열로 변환한 다음.. 각각의 자리에 시간과 분과 초에 해당하는 값들을 일일이 대입하고 각각 연산하는 경우를 보았는데.. 대략 난감하다. 실제로 오라클은 months_between 함수를 통해 두 시점간의 개월수를 구하는 함수와 trunc 와 round 함수를 통해 두 시점간의 일자수를 구하는 함수 등은 지원한다. 그리고 round 의 경우 사사오입되면 오차가 발생하므로 정확히 일자를 구분한다면 trunc 를 사용한다. 여기서 우리가 알고 싶은 것은.. 두 시점간의 시간, 분, 초를 구하는 방법이다. 기본 함수가 없기 때문에 산식으로 구현해야 한다. 미리 알아 두어야 할 것은.. 오라클은 일자를 정수의 증감으로 보고,..

오라클 DB 에서 between 이용시 유의사항

select * from tableA where colA between conA and conB ; 상기와 같이 쿼리를 할 때, conA 와 conB 의 관계는 conA conB 이면 쿼리 결과는 없다. ResultSet 에 null 이 들어온다. 가장 기본적인 내용인데, 나도 간혹 잊어버리곤 한다. 아주아주 복잡한 쿼리를 만들어 놓고는 왜 결과가 안 나오나 몇시간째 고민하다가, 위와 같은 원리를 접어 두었던 적이 한두번이 아니다. UI 에서 일자를 관리할때 From 과 To 의 관계가 역순이 되지 않도록 해야 하는 이유다. colA 가 Date 형이고, conA 와 conB 가 to_date('20091211','yyyymmdd') 와 유사한 형태라면.. 일자에 대해서는 좀더 주의를 기울여야 한다. 예..

오라클 DB 에서 DML 작업시 OCI_NO_DATA 오류가 날때 트리거가 문제라면, 잠시 disable 해 놓자

update 나 delete 시 OCI_NO_DATA 와 같은 오류 메시지가 나는 경우, DB 트리거 에서 updating 이나 deleting 쪽에 select 문이 문제를 일으키는 사례가 있다. 이때 해당 문제를 해결하는 것이 근원적인 조치가 되겠지만.. 여차저차한 이유로 잠시만 해당 트리거를 disable 시켰다가 다시 enable 할 수도 있겠다. 이때는 아래와 같이 해 주면 된다. ALTER TRIGGER [트리거명] DISABLE; ALTER TRIGGER [트리거명] ENABLE; 참고로, 컴파일을 하는 거라면.. ALTER TRIGGER [트리거명] COMPILE; 간혹 트리거가 죽어 있을때에도 enable 해 주면 된다.

connect by ~ start with ~ order siblings by ~ 문에 대한 Oracle 9i Plan (실행계획)

connect by ~ start with 문에서 정렬하는 방법. order siblings by ~ 활용. 다음은 connect 문에 넣기 전에 미리 order by 를 해 놓는 경우이다. Index 힌트를 사용하여 다른 인덱스를 태우지 않도록 제한을 걸었다 (그래도 Optimizer 마음대로 하겠지만..). 그런데, 이렇게 하면.. 실행계획이 복잡하게 된다. srart with 문이나 connect by 에도 order by 의 sort 계획이 잡히게 된다. select * from (select /*+ index(a table_category_idx04) */ a.seq_category, a.bef_category, a.name, a.depth, a.ordr, a.link_url from table..

오라클 DB 성능 향상 엑셈 MaxGauge

Maxgauge 개발회사 엑셈 홈페이지 -> http://www.ex-em.com/ -> 엑셈에서 다양한 세미나 등을 하는데 성능 관련 및 OWI 등은 들으면 도움이 되실듯 함..^^ 제품 설명 자료 -> http://www.ex-em.com/web/support/support_databank1.php?dtype=1 -> 목록중에 [MaxGauge 교육자료 Ver3.1] 를 Down 받아서 참고 제품 매뉴얼 -> http://www.ex-em.com/web/support/support_databank1.php?dtype=1 -> 목록중에 [MaxGauge 3.1(Oracle) 매뉴얼 vol.1 / 2] 를 참고 오라클 백과사전 -> http://wiki.ex-em.com/index.php/ -> 엑셈에서..

여러줄 나오는 쿼리를 한줄로 줄일때 Clob 이 대상이라면 다른 방법을 찾아 봐야..

select title, content, isrtid from tableA ; 상기 결과가 다음과 같을때.. 이걸 한 줄로 고쳐보고 있을 거다. titleA contentA isrtIdA titleB contentB isrtIdA titleC contentC isrtIdA titleD contentD isrtIdA .. 그러면 당연히 isrtid 로 group by 를 하고, max 와 decode 를 사용할 것인데.. 그렇다면 쿼리가 다음과 같이 된다. select isrtid, max(decode(title, 'titleA', content)) content1, max(decode(title, 'titleB', content)) content2, max(decode(title, 'titleC', co..

WareValley 의 Orange 와 insert into ~ select ~ 구문을 이용한 데이타 DB 업로드

이번 작업의 전체 그림은, 1. 일단 Excel 을 통해 데이타를 가공하고 2. 가공된 데이타를 Orange Loader 로 임시테이블에 올리고 3. 임시테이블의 내용을 insert into ~ select 구문으로 본 테이블에 올리는 것입니다. 데이타가 대용량이든 아니든, 일단 가공을 한다면 MS 엑셀로 하는 것이 편합니다. 물론 제한사항은 있습니다. 하나의 워크시트에 65,535 개의 로우만 관리할 수 있다는 것이죠. 이러한 제약사항 때문에 하나의 엑셀 파일에 여러개의 워크시트로 나누어 작업을 하기도 합니다. 물론 오렌지에서 여러 워크시트를 한번에 업로드 할 수 있습니다. 그리고, 일시나 숫자와 관련된 사항은 엑셀과 DB 툴을 연계하는 작업에서 다루기 힘들지요. 상황에 맞게 작업해야 하는데 텍스트면 ..

WareValley Orange, 다수의 트리거와 프로시저 본문 대상으로 검색

하나의 트리거나 프로시저에서 특정 단어를 검색하는 것은 쉽다, 일단 해당 오브젝트를 열어서 검색하면 되니까. 그러면, 테이블 이름이나 필드 이름으로 어디에 있는지도 모를 다수의 트리거나 프로시저를 검색하려면 어떻게 해야 할까. 물론, 오라클의 경우 아래 쿼리문과 같이 DB 쿼리만으로도 해당 내용을 검색할 수 있다. select * from user_source where text like '%키워드%'; 그런데 이렇게 하면 하나의 줄 단위로 검색이 되기 때문에 본문 내용을 보려면 다시 해당 프로시저를 열어야만 한다. 그리고 user_source 를 이용하기 때문에 사용자별로 검색을 하여야 한다. 여기에서는 WareValley 사의 Orange 4.0 DBA 버전으로 활용법을 알아 보겠다. 아래 그림과 같..

select .. from .. where .. connect by (prior) .. = (prior) .. start with ..

가계도를 하나의 DB 테이블에 담았다가 손쉽게 쿼리하여 가져올 수는 없을까..? 분류체계를 정해서 한눈에 보여질 수 있도록 할 수 있지 않을까..? 등등에 대해서 목마름을 씻어주는 쿼리 문법. 일단 오라클에는 있고, MySQL 에는 비슷한 다른 방식이 있다는데.. DB2 나 Sybase 등에는 어떤 것들이 있을까.. 이건 숙제다. connect by 를 이용하려면 DB 모델링에서 하나의 테이블 안에 트리 구조를 위한 조치를 해야 하는데, 자신의 코드와 트리 구조상 상위 위치의 코드 2개를 가지고 있어야 한다. 이를테면, 아래에 예를든 것에서, w2_category 테이블에는.. 자신의 코드인 seq_category 와 상위 코드인 bef_category 를 이용했다. select * from w2_cat..