SQL튜닝을 위한 도구중 하나인 "오라클의 10053 이벤트" 간단히 소개하고 오라클 함수를 만들어 간단히 테스트 후 옵티마이저의 Query Transformation, Optimization 과정(조인방법 결정, 드라이빙테이블 선정), 실행계획 생성등을 Trace 파일을 만들어 확인하는 PPT 강좌 입니다.
SQL튜닝을 위한 도구중 하나인 "오라클의 10053 이벤트" 간단히 소개하고 오라클 함수를 만들어 간단히 테스트 후 옵티마이저의 Query Transformation, Optimization 과정(조인방법 결정, 드라이빙테이블 선정), 실행계획 생성등을 Trace 파일을 만들어 확인하는 PPT 강좌 입니다.
(오라클 SQL튜닝을 위한 쿼리문 작성법 강좌)오라클 SQL/쿼리 튜닝은 간단한 SQL구문 최적화 부터 시작을 하게되죠, SQL을 처음 사용할 때 부터 최적화 하는 방법에 주의해서 공부하시면 저절로 튜닝 됩니다. 본 PPT 강좌는 탑크리에듀(www.topcredu.co.kr), 오라클자바커뮤니티(ojc.asia)에서 제공하는 교육강좌 입니다.
(쿼리 변환, Query Transformation,서브쿼리푸시,SubQuery Pushing)SQL튜닝을 위해 서브쿼리의 드라이빙을 제어...탑크리에듀(구로디지털단지역3번출구 2분거리)
(개발시 SQL튜닝은 기본 입니다.)서브쿼리튜닝, 쿼리 변환(Query Transformation)에 대한 이해는 SQL튜닝의 핵심입니다. 서브쿼리 푸시 및 서브쿼리의 드라이빙을 제어할 수 있는 push_subq, no_push_subq 힌트에 대해 알아보고 실행방법에 따른 서브쿼리의 종류도 설명한 영상 입니다. SQL튜닝 교육은 탑크리에듀(www.topcredu.co.kr)에서 해결해 드리겠습니다.
탑크리에듀(http://www.topcredu.co.kr) 제공 SQL튜닝, 오라클힌트 강좌 입니다. Subquery Factoring은 WITH구문을 이용하여 복잡한 쿼리문을 임시테이블에 저장하여 이를 이용하는 방법으로 반복되는 SELECT구문을 WITH구문에 한번만 정의하여 사용하여 쿼리 성능을 향상 시킬 수 있는 방법 입니다.
With구문은 SQL-99 표준이며 오라클에서는 9.2에 도입되었으며 복잡한 인라인뷰등을 WITH구문을 이용하여 한곳으로 몰아 가독성 또한 좋습니다.
오라클 옵티마이저는 WITH구문의 내용이 복잡할 경우 서브쿼리를 Global Temporary Table에 넣어 WITH구 블록이 여러곳에서 참조되는 경우 효율적으로 구성할 수도 있으며 Materialize 힌트는 서브쿼리 블록을 Global Temporary Table로 만들어서 사용하라는 힌트이며 Inline 힌트는 반대로 해당 WITH 쿼리블럭을 메인 쿼리블럭에 넣어 그대로 실행하라는 힌트 입니다.
본원에서는 SQL튜닝 온라인 화상강의도 무료로 진행하고 있으니홈페이지에서 확인 바랍니다. 감사합니다.
NVL(expr1, expr2)
: IF expr1 IS NULL expr2 ELSE expr1, expr1과 expr2의 DataType이 다르면 expr2를 비교전 expr1로 변환 한다.
NVL2(expr1, expr2, expr3)
: IF expr1 IS NULL THEN expr3 ELSE expr2, expr1은 어떠한 DataType 이라도 가능하며 expr2 및 expr3의 경우 LONG을 제외한 DataType이면 된다. 만약 expr2와 espr3가 DataType이 다르다면 비교전에 expr3을 expr2로 변환 한다.
서브 쿼리에서 여러 건의 결과가 반환되는 구조 이다. 이와 같은 구조에서 사용되는 연산자는 IN, ANY, SOME(ANY와 동일), ALL, EXISTS 등과 같은 복수 행 연산자 이다. 이 연산자들은 이전의 SQL 연산자 부분에 자세히 나와 있으니 참조하길 바라며 아래의 예문을 따라 하면서 이해해 보자.
탑크리에듀에서 제공하는 SQL기초강좌(상관서브쿼리) 입니다.
서브 쿼리와 메인쿼리간에 서로 상관 참조 작용하는 쿼리로 Inner Query에서 Outer Query의 어떤 컬럼을 이용하는 경우다. 일반적인 Query의 경우 서브 쿼리의 결과를 메인에서는 단순히 이용만 하지만 상관 서브 쿼리에서는 서브 쿼리가 메인 쿼리의 값을 이용하여 값을 구하면 그 값을 다시 메인 쿼리에서 이용하는 구조이므로 서브쿼리는 값을 확인하는 확인자 역할을 하게된다. 예를 들어 서브 쿼리 에서 10번 부서에서 가장 많은 급여를 받는 사람, 20번 부서에서 가장 많은 급여를 받는 사람, 30번 부서에서 같은 결과를 구하고자 한다면 부서만 다르고 같은 내용을 입력 시켜야 하므로 이 경우 상관 쿼리로 만들어 처리하면 편리 하다.
COALESCE (expr1, expr2,,,,)
: 여러 expr중 처음 NULL 아닌 요소를 리턴 한다.
GREATEST (expr1, expr2,,,,)
: 여러 expr중 최대인 것을 리턴 한다.
LEAST (expr1, expr2,,,,)
: 여러 expr중 최소인 것을 리턴 한다.
서브 쿼리는 SELECT한 결과를 조건 비교시 사용하거나 UPDATE, INSERT등에 사용되는 내장된 SELECT 문장이며 메인 쿼리 이전에 한번만 실행 된다. 테이블 자체의 데이터에 의존하는 조건으로 테이블의 행을 검색할 필요가 있을 때 서브쿼리는 아주 유용하게 이용될 수 있다
ROWNUM은 의사 칼럼으로 참조만 될 뿐 데이터베이스에 저장되지 않는다. (DESC 명령으로 보이지 않는 의사 칼럼). SELECT절에 의해 추출되는 데이터(ROW)에 붙는 순번이다. 다시 말해 WHERE절까지 만족 시킨 자료에 1부터 붙는 순번이다. WHERE절에 ROWNUM을 이용하여 조건을 주면 다른 조건을 만족시킨 결과에 대해 조건이 반영된다. SELECT 리스트에 ROWNUM을 이용하는 것도 물론 가능하다. ORDER BY를 사용한다면 WHERE절까지 만족 시킨 결과에 ROWNUM이 붙은 상태로 ORDER BY가 반영된다. 즉 ROWNUM은 ORDER BY전에 부여되며, ORDER BY는 맨 나중에 실행된다.
해시 클러스터는 Cluster Index를 사용하지 않는 부분을 제외하면 Indexed Cluster와 유사한 구조이며 저장되는 데이터가 곧 인덱스가 되는 구조이다.
해시 클러스터를 가진 테이블에서 힌트의 인자로 기술한 테이블에 대해 HASH SCAN이 일어나도록 하는 힌트이며 USE_HASH(해시 조인이 일어나도록 하는 힌트)와 구별된다. HASHKEYS parameter를 가지고 만들어진 HASH CLUSTER내에 저장된 테이블에서만 적용 된다.
다량의 범위를 자주 액세스해야 하는 경우나 인덱스를 사용한 처리가 부담이 되는 범위(넓은 분포도), 수정이 자주 발생하지 않는 Column, 대규모 테이블, 여러 개의 테이블이 빈번한 조인을 일으킬 때 CLUSTER INDEX를 사용하면 되는데 HASH CLUSTER에 테이블을 저장하는 것은 데이터 검색의 성능을 향상하기 위한 선택적인 방법이다.
(오라클 SQL튜닝을 위한 쿼리문 작성법 강좌)오라클 SQL/쿼리 튜닝은 간단한 SQL구문 최적화 부터 시작을 하게되죠, SQL을 처음 사용할 때 부터 최적화 하는 방법에 주의해서 공부하시면 저절로 튜닝 됩니다. 본 PPT 강좌는 탑크리에듀(www.topcredu.co.kr), 오라클자바커뮤니티(ojc.asia)에서 제공하는 교육강좌 입니다.
(쿼리 변환, Query Transformation,서브쿼리푸시,SubQuery Pushing)SQL튜닝을 위해 서브쿼리의 드라이빙을 제어...탑크리에듀(구로디지털단지역3번출구 2분거리)
(개발시 SQL튜닝은 기본 입니다.)서브쿼리튜닝, 쿼리 변환(Query Transformation)에 대한 이해는 SQL튜닝의 핵심입니다. 서브쿼리 푸시 및 서브쿼리의 드라이빙을 제어할 수 있는 push_subq, no_push_subq 힌트에 대해 알아보고 실행방법에 따른 서브쿼리의 종류도 설명한 영상 입니다. SQL튜닝 교육은 탑크리에듀(www.topcredu.co.kr)에서 해결해 드리겠습니다.
탑크리에듀(http://www.topcredu.co.kr) 제공 SQL튜닝, 오라클힌트 강좌 입니다. Subquery Factoring은 WITH구문을 이용하여 복잡한 쿼리문을 임시테이블에 저장하여 이를 이용하는 방법으로 반복되는 SELECT구문을 WITH구문에 한번만 정의하여 사용하여 쿼리 성능을 향상 시킬 수 있는 방법 입니다.
With구문은 SQL-99 표준이며 오라클에서는 9.2에 도입되었으며 복잡한 인라인뷰등을 WITH구문을 이용하여 한곳으로 몰아 가독성 또한 좋습니다.
오라클 옵티마이저는 WITH구문의 내용이 복잡할 경우 서브쿼리를 Global Temporary Table에 넣어 WITH구 블록이 여러곳에서 참조되는 경우 효율적으로 구성할 수도 있으며 Materialize 힌트는 서브쿼리 블록을 Global Temporary Table로 만들어서 사용하라는 힌트이며 Inline 힌트는 반대로 해당 WITH 쿼리블럭을 메인 쿼리블럭에 넣어 그대로 실행하라는 힌트 입니다.
본원에서는 SQL튜닝 온라인 화상강의도 무료로 진행하고 있으니홈페이지에서 확인 바랍니다. 감사합니다.
NVL(expr1, expr2)
: IF expr1 IS NULL expr2 ELSE expr1, expr1과 expr2의 DataType이 다르면 expr2를 비교전 expr1로 변환 한다.
NVL2(expr1, expr2, expr3)
: IF expr1 IS NULL THEN expr3 ELSE expr2, expr1은 어떠한 DataType 이라도 가능하며 expr2 및 expr3의 경우 LONG을 제외한 DataType이면 된다. 만약 expr2와 espr3가 DataType이 다르다면 비교전에 expr3을 expr2로 변환 한다.
서브 쿼리에서 여러 건의 결과가 반환되는 구조 이다. 이와 같은 구조에서 사용되는 연산자는 IN, ANY, SOME(ANY와 동일), ALL, EXISTS 등과 같은 복수 행 연산자 이다. 이 연산자들은 이전의 SQL 연산자 부분에 자세히 나와 있으니 참조하길 바라며 아래의 예문을 따라 하면서 이해해 보자.
탑크리에듀에서 제공하는 SQL기초강좌(상관서브쿼리) 입니다.
서브 쿼리와 메인쿼리간에 서로 상관 참조 작용하는 쿼리로 Inner Query에서 Outer Query의 어떤 컬럼을 이용하는 경우다. 일반적인 Query의 경우 서브 쿼리의 결과를 메인에서는 단순히 이용만 하지만 상관 서브 쿼리에서는 서브 쿼리가 메인 쿼리의 값을 이용하여 값을 구하면 그 값을 다시 메인 쿼리에서 이용하는 구조이므로 서브쿼리는 값을 확인하는 확인자 역할을 하게된다. 예를 들어 서브 쿼리 에서 10번 부서에서 가장 많은 급여를 받는 사람, 20번 부서에서 가장 많은 급여를 받는 사람, 30번 부서에서 같은 결과를 구하고자 한다면 부서만 다르고 같은 내용을 입력 시켜야 하므로 이 경우 상관 쿼리로 만들어 처리하면 편리 하다.
COALESCE (expr1, expr2,,,,)
: 여러 expr중 처음 NULL 아닌 요소를 리턴 한다.
GREATEST (expr1, expr2,,,,)
: 여러 expr중 최대인 것을 리턴 한다.
LEAST (expr1, expr2,,,,)
: 여러 expr중 최소인 것을 리턴 한다.
서브 쿼리는 SELECT한 결과를 조건 비교시 사용하거나 UPDATE, INSERT등에 사용되는 내장된 SELECT 문장이며 메인 쿼리 이전에 한번만 실행 된다. 테이블 자체의 데이터에 의존하는 조건으로 테이블의 행을 검색할 필요가 있을 때 서브쿼리는 아주 유용하게 이용될 수 있다
ROWNUM은 의사 칼럼으로 참조만 될 뿐 데이터베이스에 저장되지 않는다. (DESC 명령으로 보이지 않는 의사 칼럼). SELECT절에 의해 추출되는 데이터(ROW)에 붙는 순번이다. 다시 말해 WHERE절까지 만족 시킨 자료에 1부터 붙는 순번이다. WHERE절에 ROWNUM을 이용하여 조건을 주면 다른 조건을 만족시킨 결과에 대해 조건이 반영된다. SELECT 리스트에 ROWNUM을 이용하는 것도 물론 가능하다. ORDER BY를 사용한다면 WHERE절까지 만족 시킨 결과에 ROWNUM이 붙은 상태로 ORDER BY가 반영된다. 즉 ROWNUM은 ORDER BY전에 부여되며, ORDER BY는 맨 나중에 실행된다.
해시 클러스터는 Cluster Index를 사용하지 않는 부분을 제외하면 Indexed Cluster와 유사한 구조이며 저장되는 데이터가 곧 인덱스가 되는 구조이다.
해시 클러스터를 가진 테이블에서 힌트의 인자로 기술한 테이블에 대해 HASH SCAN이 일어나도록 하는 힌트이며 USE_HASH(해시 조인이 일어나도록 하는 힌트)와 구별된다. HASHKEYS parameter를 가지고 만들어진 HASH CLUSTER내에 저장된 테이블에서만 적용 된다.
다량의 범위를 자주 액세스해야 하는 경우나 인덱스를 사용한 처리가 부담이 되는 범위(넓은 분포도), 수정이 자주 발생하지 않는 Column, 대규모 테이블, 여러 개의 테이블이 빈번한 조인을 일으킬 때 CLUSTER INDEX를 사용하면 되는데 HASH CLUSTER에 테이블을 저장하는 것은 데이터 검색의 성능을 향상하기 위한 선택적인 방법이다.
The MyBatis data mapper framework makes it easier to use a relational database with object-oriented applications. This document explain about MyBatis basic concept.
DBMS_STATS 패키지에는 몇 개의 유용한 프러시저가 있는데 아래와 같다.
gather_database_ stats: 데이터베이스의 모든 Object에 대한 통계 정보 생성.
gather_schema_ stats: 해당 스키마의 모든 Object에 대한 통계 정보 생성.
gather_table_stats : 테이블과 그 테이블과 연관된 인덱스에 대한 통계 정보 생성.
gather_index_stats : 인덱스에 대해 통계 정보를 생성.
탑크리에듀(http://www.topcredu.co.kr), 오라클자바커뮤니티(http://ojc.asia)에서 제공하는 온라인 무료 화상교육, 오라클 SQL힌트/튜닝 강의자료 3회차 입니다. 12월22일 진행되는 교육에서는 중첩루프조인 소개 및 USE_NL, USE_NL_WITH_INDEX, ORDERED 힌트 구문에 대해 살펴볼 예정 입니다.
2. 1. SELECT * ... 문장은 피하세요.
쿼리의 결과로 모든 필드의 결과가 필요한 경우가 아니라면 SELECT리스트에 필요
한 필드들을 일일이 적어 주어야 합니다. 즉, "SELECT * From Table" 과 같은 쿼
리는 "SELECT Field1, Field2 From Table ..."과 같이 필요한 필드를 밝힌 쿼리로
작성하기 바랍니다.
2. 알맞은 인덱스를 구성해서 쿼리가 인덱스를 타게 하세요.
(효율적으로 인덱스를 구성하고 사용한다면 쿼리의 속도를, 그리고 궁극적으로는
DB 서버의 퍼포먼스를 놀라울 정도로 향상시킬 수 있습니다.)
3. 3. 쿼리가 여러 번 DB서버에 들어가지 않게 하세요.
만일 웹 서버가 DB 서버에 데이터를 요청할 때 저장 프로시저를 사용하지 않고 웹
서버에서 작성한 쿼리를 DB서버에 보내는 방식이라면, 되도록 쿼리가 DB서버에
자주 들어가지 않도록 작성하기 바랍니다.
ex. 루프 내에서 단순한 SELECT쿼리를 계속 부르는 실수입니다. 이러한 경우에는
필요한 데이터를 모두 SELECT해서 가져온 다음에 레코드셋을 가지고 루프 연산을
수행하는 것이 좋습니다.
ex. UPDATE 쿼리를 사용할 때 종종 실수를 하는 일이 있습니다. 어떤 값을 하나
증가시키기 위해 해당 값을 일단 SELECT 해 와서 그 값을 하나 증가시킨 뒤에 데
이터를 업데이트하는 경우가 있습니다.
이런 경우에는 당연히 "UPDATE Table SET Field = Field + 1 WHERE ..."와 같
은 쿼리로 해당 값을 SELECT하지 말고 한번의 UPDATE쿼리로 처리하는 것이 좋
습니다.
ex. 서브쿼리가 있다는 것을 인식하지 못하는 데서 일어나는 실수도 있습니다.
(즉, SELECT쿼리를 통해서 데이터를 반환 받고 반환 받은 값을 변환한 다음,
INSERT쿼리를 통해서 변환한 값을 다른 테이블에 넣는 경우가 이러한 예에 해당합
니다.)
4. 4. JOIN쿼리에서 사용 메모리를 줄이는 방법을 생각하세요.
기본적으로 JOIN (여기에서는 Inner Join)을 사용하면 ON 절에 밝힌 조건에 의해
서 데이터를 추린 다음 WHERE 절 조건을 적용합니다. 따라서 ON 절 조건에 의해
추려지는 데이터는 메모리에 설정됩니다.
이때 아예 JOIN을 피할 수 있도록 테이블을 구성할 수 있다면 그렇게 하는 것이 가
장 좋은 방법이겠지만, 그렇게 할 수 없다면 되도록 JOIN 할 때 설정되는 임시 메
모리의 크기가 작게 만들어지도록 두 테이블에서 값은 같지만 메모리는 더 작게 차
지하는 필드를 찾아 그것을 ON조건에 사용하는 것이 유리합니다.
5. SELECT가 많다면 NOLOCK 힌트를 줄 수도 있어요. ( NOLOCK이란 DB서버
내부적으로 해당 데이터를 읽고 있음을 표시해 주는 LOCK을 설정하지 않는 것을
의미합니다.)
서비스 내용 구성상 SELECT 쿼리는 자주 일어나는데 INSERT나 UPDATE쿼리는
거의 일어나지 않는 환경이라면
"SELECT Field1 FROM Table (NOLOCK) ..."과 같이 NOLOCK 힌트를 주면 좋습
니다.
참고로 NOLOCK힌트의 단점은 NOLOCK을 쓰게 되면 변화된 데이터 내용을 반영
하지 않거나, 데이터가 변경 중이라도 데이터를 읽어 오는 현상이 일어날 수 있기
때문에 사용상의 주의가 요구됩니다. 다이내믹 타입의 레코드셋을 사용하는 것과
같이 변경된 값이 바로 반영되어야 하는 환경이 아니라면 크게 문제 되지는 않을 것
이지만요.
5. 6. TOP을 이용해서 필요한 만큼만 부르세요.
"SELECT * ..."가 불필요한 데이터까지 다 반환하는 좋지 못한 예였다면, TOP을
사용하지 않아서 필요도 없는 데이터 행(Row)까지 반환하는 것도 비슷한 맥락에서
퍼포먼스를 저하시키는 예라고 할 수 있습니다.
예를 들어 서비스의 한 웹 페이지에 게시판 목록을 보여주는 기능, 즉 어떤 자료에
대한 리스트를 10개 보여 주고 다음 페이지로 넘어가면 다음 리스트 10개를 보여
주는 페이지를 작성한다고 합시다. 그러면 처음 웹 페이지를 구성하는 데에 필요한
데이터는 10개인데도 불구하고 모든 데이터 행을 다 SELECT해 온 다음, 웹 스크
립트에서 루프를 10번 돌리면서 페이지를 꾸미는 경우를 자주 보았습니다. 이렇게
하면 리스트 페이지를 하나씩 넘어갈 때마다 전체 데이터가 반환되므로 네트워크
부하는 물론이고 웹 서버와 DB 서버의 메모리 부하도 커지게 되므로 결코 좋은 방
법이라고 할 수 없습니다. 이런 경우에는 "SELECT TOP n ..."과 같이 TOP을 써서
필요한 수만큼 데이터를 반환하도록 해 줍니다.
7. 빠른 데이터 개수 반환 팁을 쓰세요.
테이블에 저장되어 있는 데이터의 총 개수를 알아내기 위해서
"SELECT COUNT (PromaryKeyField) ..." 혹은 "SELECT
COUNT(*) ..."와 같이 COUNT함수를 사용하는 경우가 있습니다. 이것이 잘못되
었다는 말이 아니고 만일 테이블에 있는 데이터 행의 총 개수를 알아내고자 하는 경
우라면
"SELECT rows FROM sysindexes WHERE id = OBJECT_ID('Table이름') AND
indid <2" 의 쿼리를 사용하는 편이 속도가 훨씬 빠르다는 것입니다. (총 개수를
구하고자 할 때 사용하며, 일부 개수를 구할 수는 없습니다.)
6. 8. 뷰나 스토어드 프로시져를 사용하세요.
긴 쿼리문을 네트웍으로 전송하는것에 비해 뷰나 스토어드 프로시져는 그 이름만
전송하기 때문에(파라미터가 있다면 이것도 포함) 네트웍 트래픽을 감소시킬 수 있
습니다.. 게다가 보안관리까지 할 수 있기 때문에 여러분이 사용자에게 숨겨야하는
컬럼의 액세스 제한을 할 수 있습니다.
9. 가능한 한 SQL Server 커서의 사용을 피하세요.
SQL Server 커서는 select문에 비해 성능상에 좋지 않습니다.. 행 단위의 처리가
필요하다면 상관질의나 유도된 테이블을 사용하도록 노력해보세요.
10. 트리거 대신에 제약조건을 사용하세요.
제약조건은 트리거보다 성능면에서 훨씬 효율적입니다. 따라서 가능한 한 제약조건
을 사용하세요.
11. 임시테이블 대신 테이블 변수를 사용하세요.
테이블 변수는 임시테이블에 비해 잠금과 로깅 작업에 적은 리소스가 소모됩니다..
따라서 가능한 한 테이블 변수를 사용하세요.
7. 12. HAVING절의 사용은 피하세요.
Having절은 GROUP BY에 의한 결과를 제한할 때 사용합니다.. GROUP BY에
Having절을 사용하였을 경우 GROUP BY에 의해서 결과들을 모두 집계한 다음
Having절에 명시한 조건으로 맞지 않는 결과를 버리게 됩니다.. 대부분의 경우
Having절의 필요 없이 GROUP BY와 Where절만으로 원하는 결과를 얻을 수 있습
니다..
13. 가능한 한 DISTINCT 문의 사용을 피하세요.
DISTINCT문을 사용할 경우 소트에 따른 성능 하락이 있기 때문에 꼭 필요한 경우
에만 사용하세요.
14. 결과에 적용된 행의 갯수를 표시하지 않아도 된다면 프로시져에 SET
NOCOUNT ON을 추가해보세요.
몇개의 행이 적용되었는지가 전달되지 않기 때문에 네트웍 트래픽이 감소합니다.
15. 가능한 한 UNION 대신에 UNION ALL을 사용하세요.
UNION ALL이 UNION보다 훨씬 빠릅니다.. 왜냐하면 UNION ALL은 로우의 중복
검사를 하지않는 반면에 UNION은 중복행이 있건 없건간에 중복검사를 수행하기
때문입니다.