이 블로그 검색

레이블이 오라클인 게시물을 표시합니다. 모든 게시물 표시
레이블이 오라클인 게시물을 표시합니다. 모든 게시물 표시

2011년 9월 28일 수요일

오라클 인덱스2

※ 인덱스생성 명령을 실행하면 해당 테이블에 테이블락이 자동으로 걸린다.
그래서 서비스상태에서는 인덱스를 주면 장애가 날수 있습니다.

Index 정의

1) 조회속도를 향상시키기 위한 데이터베이스 검색 기술

2) 색인이라는 뜻으로 해당 테이블의 조회결과를 빠르게 하기 위해 사용합니다.
보통 INDEX를 테이블의 특정 컬럼에 한개이상을 주게 되면 Index table 이 따로 만들지는데
이 INDEX table 에는 인덱스컬럼의 로우의 값과 rowid 값이 저장되게 되며 로우의값은 정렬된 B-TREE 구조로 저장시켜두어 검색시 좀더 빠르게 해당 데이타를 찾는데 도움을 준다.
하지만 UPDATE,INSERT,DELETE 시에 속도가 느려진다는 단점이 있다.
왜냐하면 INSERT, UPDATE, DELETE 시에는 원본TABLE은 물론 INDEX table 에도 데이타를 갱신시켜 주어야 하기 때문입니다.
하지만 너무 작은 로우(레코드)가 있는 TABLE에 INDEX를 사용하게 되면 index의 효력을 제대로 발휘못하며 반드시 INDEX키를 조건으로 검색시에는 연산이나 가공을 하면 INDEX를 탈수없다.

※ 테이블을 생성하고 컬럼을 만든후 데이타를 삽입하면 하나의 로우가 생성되며 이 로우는 절대적인 주소를 가지게 됩니다. 이 절대적인 주소를 ROWID 라고 합니다.

INDEX가 필요한 이유?

조회 속도를 최대한 줄일수 있다.

참고
인덱스를 만들 때 현재 컬럼수가 너무 많으면 DML의 성능이 떨어지고 너무 부족하면
쿼리의 성능이 떨어집니다. 데이터가 많고 B*Tree Index인 경우 컬럼level이 하나
늘어날 때 그에 따른 node의 추가가 엄청나게 일어날 수 있습니다
이런 node들이 너무 많으면 쿼리성능도 좋을 수 없습니다.
인덱스는 일반적으로 최대 5개 컬럼 내외정도로 상황에 따라 합리적으로 구성합니다.

INDEX가 필요한 경우?

1) 데이터가 적은(수천건 이상) 경우이거나 조회속도가 너무 느리면 인덱스를 설정하는
것이 성능이 좋습니다.

2) 조회결과가 전체 데이타수의 3~5% 미만일 경우에 인덱스스캔이 효율적이고
적은비용으로 빠르게 데이터를 찾아낼수있습니다.
하지만 Acess 대상범위가 전체범위의 3~5%이상쯤 되면 인덱스스캔 보다 풀스캔이 휠씬
유리합니다.

인덱스 스캔 = Index Scan
풀 스캔 = Full Scan

INDEX가 불필요한 경우?

1) 데이터가 적은(수천건 미만) 경우에는 인덱스를 설정하지 않는게 오히려 성능이 좋습니다.
2) 조회 보다 삽입, 수정, 삭제 처리가 많은 테이블
3) 조회결과가 전체행의 15% 이상 읽어들일것으로 예상될때

Index 튜닝의 시기단계

하드웨어
DBMS 환경체크 - INDEX설정 및 파티셔닝체크 - SQL최적화  등의 레벨 순서로 튜닝합니다.

소프트웨어
쿼리문의 조회조건이 인덱스를 타는지 체크한다.(조금 중요)

쿼리문의 JOIN키가 모두 INDEX 설정이 되어 있는지 체크한다. INDEX설정이 되어 있지 않는 컬럼을 JOIN키로 지정했다면 조회속도가 많이 느려질수 있다.(많이 중요)

INDEX 생성하는 방법?

자동 생성

유일 인덱스는 테이블 정의시 PRIMARY KEY와 UNIQUE KEY 제약조건을 정의할때 자동으로 생성한다.

수동 생성

사용자는 행에 대한 액세스 시간을 향상 시키기 위해 열에서 유일하지 않은 인덱스를 생성할수 있다.

INDEX 생성 문법?

사용형식

CREATE INDEX index_name ON table_name (column_name)
--단일 인덱스 지정
CREATE INDEX index_name ON table_name (column_name1,column_name2,column_name3)
--다중 인덱스(복합 인덱스) 지정

※ 복합 인덱스로 지정해준 테이블에서 복합 인덱스를 타게 하려면 복합 인덱스로 준 컬럼
을 조회쿼리에서 모두 조회조건에 사용해야 인덱스를 탈 확률이 높아진다.

사용예제

create index index_a_date on account(a_date);
create index index_a_date on account(a_date, b_date, c_date);

※ null 허용 컬럼은 인덱스를 만들수 없습니다.

INDEX 가능 컬럼

인덱스는 모든 컬럼에 적용가능하다.
그런데 오라클은 가공시킨 컬럼에도 적용가능하다. 아래 참고

CREATE INDEX IDX_NAME ON TABLE_NAME(ROUND(PRICE1-PRICE2));

ROUND(PRICE1-PRICE2) 는 컬럼은 아니지만 컬럼을 가공해서 만든것이다.
이런 가공컬럼은 다음과 같은 SQL 쿼리로 인덱스를 탈수 있다.

SELECT * FROM TABLE_NAME WHERE ROUND(PRICE1-PRICE2) > 0

※ 인덱스 줄때의 가공컬럼과 같아야 합니다.

SQL 쿼리의 INDEX SCAN 유무 체크 방법

1. 상용 DB 관리도구를 이용하는 방법

PL/SQL Developer, Toad 같은 도구에서 SQL문을 작성하고 실행하면 Explain plan 에서 확인 가능합니다.

INDEX를 사용해야할 컬럼은?

where절이나 조인 조건에서 자주 사용되는 열에 생성
열은 광범위한 값을 포함할때
열은 많은수의 null값을 포함할때
조회결과가 전체행의 2-4% 보다 적게 읽어들일것으로 예상될때
--테이블이 클때 적은 양의 로우를 검색할때 인덱스를 줍니다. 적은 양을 검색하는데 테이블을 전체 풀스캔하면 시간이 오래 걸려서 꼭 index를 줘야 합니다.

INDEX를 사용하지 말아야할 컬럼은?

테이블에 데이타가  작은 경우
where절에 자주 사용되지 않는 열은 사용되지 않는다.
조회결과가 전체행의 2-4% 이상을 읽어들일것으로 예상될때
테이블이 자주 갱신된다.

INDEX 생성시 고려사항?

고려사항

인덱스가 적용된 컬럼이 조건식에서 인덱스를 탈수있게  하려면 해당컬럼을 가공하지않거나 연산을 하지 않은 상태에서 비교해야 인덱스를 탑니다.
예를들어 연락처컬럼의경우(016-293-1965) 016 만 따로 문자열을 잘라(가공) 조건검색하면 인덱스를 타지 않습니다.
왜냐하면 인덱스 컬럼에 변형이 일어나면 상대값과 비교되기 전에 먼저 가공이 된 후에 비교된다.하지만 인덱스는 가공되기 전의 값으로 생성되어 있기 때문에 당연히 인덱스를 사용할 수 없게 된다. 여기에서 외부적(External) 변형이란 사용자가 인덱스를 가진 컬럼을 어떤 SQL함수나 사용자 지정함수(User Defined Stored Function), 연산, 결합(||) 등으로 가공을 시킨 후에 발생되는 것이며 이러한 경우는 인덱스를 탈수 없어 변형이 일어나지 않도록 제대로 기술해야 합니다.
그렇기때문에 016과 293과 1965를 각각의 컬럼으로 만들어 저장한후 각각의 컬럼에 인덱스를 주면
아무런  가공없이 조건 검색이 가능하므로 인덱스를 탈수 있습니다.

테이블 컬럼에 인덱스가 있따면 테이블 컬럼을 변경하는것보다 비교값을 변경하여
비교해주는데 좋다. 왜냐면 그래야 인덱스를 타기 때문이다.
WHERE to_char(joindate, 'yyyymmdd') = '20070612'
WHERE joindate = TO_DATE('20070612','yyyymmdd')

아래는 인덱스를 타지 않습니다.

SELECT * FROM ACCOUNT WHERE A_DAY+1>2;
SELECT * FROM ACCOUNT WHERE SUBSTR(A_STRDAY,1,1)='월';
SELECT * FROM EMP WHERE  EMP_ID = NVL(EMP_ID,'10');

아래는 인덱스를 탑니다.

SELECT * FROM ACCOUNT WHERE A_STRDAY='월요일';
SELECT * FROM ACCOUNT WHERE A_DAY>2;
SELECT * FROM    EMP WHERE  EMP_ID = NVL('10','20');
SELECT * FROM ACCOUNT WHERE A_STRDAY like '월요일%';

※ 첫번째 쿼리부터 인덱스효과가 크게 나타나는 순입니다.

INDEX 타는 경우와 안타는 경우

안타는 경우
1. SELECT * FROM emp WHERE empno <> '7369';

※ 오라클에서는 인덱스 타게 가능(exists 이용)
SELECT * FROM emp WHERE not exists
(select empno FROM emp WHERE empno = '7369' and a.empno = b.empno);

INDEX 보기?

SELECT * FROM USER_INDEXES
--데이터 사전 뷰는 인덱스의 이름과 그것의 유일성을 디스플레이 합니다.

SELECT * FROM USER_IND_COLUMNS
--뷰는 인덱스명,테이블명,열명을 디스플레이 합니다.

SELECT * FROM ALL_OBJECTS where object_type='INDEX';
--현재 계정에 생성된 모든 인덱스 보기(속도느림)

SELECT * FROM USER_OBJECTS WHERE OBJECT_TYPE='INDEX';
--현재 계정에 생성된 모든 인덱스 보기(속도빠름)

select ic.index_name,
       ic.column_name,
       ix.uniqueness
from   user_indexes ix, user_ind_columns ic
where  ic.index_name = ix.index_name
and    ic.table_name = 'ACCOUNT';
--ACCOUNT TABLE의 인덱스 정보를 검색합니다.

INDEX 삭제?
사용형식
DROP INDEX INDEX_NAME;
사용예제
DROP INDEX BYC_LOVE_IDX;

※ TABLE이 삭제되면 INDEX도 삭제된다.
※ 인덱스의 소유자와 DROP ANY INDEX권한을 가진 사람만 인덱스 삭제가 가능합니다.

datecolumn => '20060517' and datecolumn <= '20060517' 좌측의 쿼리가 인덱스 안
타는 경우
1. 인덱스키가 아님
2. 복합키 인덱스인데 첫번째 컬럼에 조건을 안준 경우
3. 인덱스 스캔을 했을때 전체 데이터의 10~15% 이상이 되어 옵티마이져가 판단했을때
4. 인덱스 스캔이 불리하다고 판단되어 강제로 인덱스안타는 풀스캔 타는 경우
5. 좌변이 가공되어 인덱스 안탐

자주 쓰이지 않는 통계용 쿼리에는 인덱스를 주지 않는다.
여기서 인덱스를 준다는 얘기는 조건절에 인덱스를 안타는 컬럼에 인덱스를 생성해준다는
얘기이다. 이때는 create temp table as 해서 임시 테이블 만들어 통계 내용을 모두 담은후에
해당 조건컬럼에 인덱스를 만들어 쿼리하는게 좋다.

오라클 인덱스1


테이블의 데이터들은 데이터파일내에 위치하게 되고, 이를 검색하기 위해서는 많은 수의 레코드들을 비교해야 합니다.
그래서 특정 필드들을 이용해서 B+트리를 구성해 놓는 것을 인덱스하고 보시면 되겠습니다.
자료구조에서 트리의 경우는 검색이 빠르다는 장점을 가지고 있죠.
결국 테이블의 데이터를 가지고 인덱스를 만들어서 검색속도를 향상시키는 것입니다.
대부분의 DB에서 기본적으로 primary key는 인덱스를 자동으로 생성하는 경우가 많습니다.
물론 이 인덱스의 종류는 다양합니다. 데이터의 종류나 성향에 따라서 검색속도를 향상시키는 몇가지의 방법이 존재하는 것이죠.
이 인덱스는 검색 쿼리문의 조건절에 명시된 조건절을 따르게 됩니다.
조건이 많은 경우는 디비내의 옵티마이져가 선택한 인덱스를 이용해서 검색을 하게 됩니다.(이는 디비마다의 알고리즘이 다릅니다.)
그래서 오라클의 경우는 옵티마이져가 정한 인덱스가 아닌, 개발자/DBA가 정한 인덱스를 타도록 지정하는 힌트라는 옵션도 있습니다.
결론적으로 인덱스는
1. 검색속도 향상을 위한 것이다.
2. 내부적으로 B+ 트리를 이용한다.
3. 데이터의 성향에 따라서 다양한 인덱스가 존재한다.
4. INSERT/UPDATE/DELETE시는 인덱스가 성능을 약화시킨다.
5. 인덱스가 다수 존재하는 경우 조건절에 따라서 타는 인덱스가 달라진다.
이정도의 특성이 있겠습니다.

-----------------------------------------------------------------------------


결합인덱스의 생성지침

- 단 하나의 테이블에서 컬럼들을 참조해야 한다
- 최대 16개 컬럼을 생성할 수 있다
- 결합 인덱스의 전체 컬럼 길이는 db_block_size 파라미터의 값을 1/2을 초과하면 안된다.
- 결합 인덱스를 생성할 때는 선택도가 좋은 컬럼을 선행컬럼으로 결정해야한다(즉 앞에 둔다)
- 선행 컬럼을 결정하기 힘든 경우에는 자주 사용되는 컬럼을 선행 컬럼으로 결정한다.
- 결합인덱스의 수가 많으면 많을수록 데이터의 검색속도는 향상될 수 있으나 오히려
  DML문의 수행성능은 저하될 수 있다

index의 분석
-최초로 인덱스를 생성한 이후 테이블에 DML문이 자주 발생하게 되면 밸런스 구조는 깨지고
 좌,우의 구조도 달라지게 된다

 이러한 현상이 발생하면 좋은 성능을 보장해 줄 수 없기 때문에 데이터 베이스 관리자는
 주기적으로 또는 비 주기적으로 밸런싱이 깨진 인덱스를 분석하고 인덱스를 재구성하는 작업을
 해야만 성능을 기대할 수 있다. 인덱스의 각 블록에 저장되어 있는 인덱스 키의 개수가 블록
 마다 틀리게 되면 밸런싱이 깨지게 된다.

-----------------------------------------------------------------------------------------------------------------


*인덱스의 밸런싱 구조상태를 확인하는 방법
SQL> analyze index i_big_emp_cp_empno validate structure;
인덱스가 분석되었습니다.

SQL> select (del_lf_rows_len/ lf_rows_len) * 100 as "Balancing"
          from index_stats;
 Balancing
----------
         0   <--완벽한 밸런싱을 유지함


-------------------------------------------------------------
-밸런싱을 깨기위해 행 삭제

SQL> delete big_emp_cp
        where empno > 1 and empno < 3000;
2879 행이 삭제되었습니다.

SQL> analyze index i_big_emp_cp_empno validate structure;
인덱스가 분석되었습니다.

SQL> select (del_lf_rows_len/ lf_rows_len) * 100 as "Balancing"
         from index_stats;
 Balancing
----------
9.49721286 <--인덱스의 밸런스 정도가 9.49%정도 깨짐

*인덱스의 재구성

-일반적으로 인덱스 밸런싱이 20%정도를 초과하면 성능이 저하될 수 있다고 본다
 좋은 성능을 기대하기 위해서는 반드시 인덱스를 재구성해야 한다.

SQL> alter index i_big_emp_cp_empno rebuild nologging;
인덱스가 변경되었습니다.

SQL> analyze index i_big_emp_cp_empno validate structure;
인덱스가 분석되었습니다.

SQL>  select (del_lf_rows_len/ lf_rows_len) * 100 as "Balancing"
  2   from index_stats;

 Balancing
----------
         0
SQL>

2011년 7월 12일 화요일

2011년 5월 3일 화요일

ORA-29275 : 부분 다중 바이트 문자

원인
서버와 클라이언트의 CHARACTERSET이 다름
해결
아래의 쿼리문을 통해 서버의 CHARACTERSET을 확인한다.
SELECT * FROM SYS.PROPS$ WHERE NAME = 'NLS_CHARACTERSET'
클라이언트의 CHARACTERSET을 변경
레지스트리편집기를 실행시킨후
HKEY_LOCLA_MACHINE\SOFTWARE\ORACLE\KEY_xxxx: 근처에서 NLS_LANG값을 확인한후 서버와 일치시켜준다.
참고로 필자의 NLS_LANG값은 KOREAN_KOREA.KO16MSWIN949 에서 KOREAN_KOREA.KO16KSC5601 로 변경

2011년 2월 10일 목요일

시퀀스/테이블 존재여부

SELECT SEQUENCE_NAME
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = 'CHUNG_20110311'

테이블의 경우  SEQUENCE대신 TABLE를 넣으면됨

2011년 1월 27일 목요일

임의 정렬

8i(or higher) 이후에 참 편리한 기능이 많이 추가되었는데

그 가운데 하나가 ORDER BY 절에서 함수를 사용할 수 있다는 것입니다.

SELECT *
FROM tab
ORDER BY DECODE(book,'Y','1','B','2','U','3','A','4')

이렇게 적어주시면 book 컬럼의 Y 값이 정렬될 때는 1 로 치환되어 가장 앞에 오게 됩니다.

DECODE 함수로 적어주기에 복잡한 규칙이라면,
CASE 구문을 사용하셔도 됩니다.

여러 SQL에서 공통으로 사용한다면 사용자정의 함수를 생성하여 활용할 것을 추천해 드립니다.

정렬하는 규칙이 변경되거나 그 양이 매우 많다면
정렬 기준만을 담은 테이블을 만들고 조인하여 사용하는 것이 
인덱스 활용면에서 더 좋을 것입니다.

2010년 10월 12일 화요일

오라클 함수

단일행 함수

 - 
문자형 함수
 UPPER : 
모든 문자를 대문자로 전환 
 LOWER : 
모든 문자를 소문자로 전환 
 INITCAP : 
문자를 단어별로 앞머리는 대문자 나머지는 소문자로 전환 
 CONCAT : 
 문자열을 합성. ||연산자와 같은 용도로 사용
 SUBSTR : 
특정문자열의 부분을 선택 
 LENGTH : 
문자열의 길이를 구함 
 LPAD : 
왼쪽 문자 자리를 채움 
 RPAD : 
오른쪽 문자 자리를 채움 
 LTRIM : 
왼쪽 문자를 지움 
 RTRIM : 
오른쪽 문자를 지움 
 TRANSLATE : 
특정 문자열을 대체 
 REPLACE : 
특정 문자열을 대신 

 UPPER(
문자값) : UPPER('Oracle Server')
 → ORACLE SERVER 
 LOWER(
문자값) :  LOWER('Oracle Server')
 → oracle server 
 INITCAP(
문자값) :  INITCAP('Oracle Server')
 → Oracle Server 
 CONCAT(
문자값1,  문자값2) :  CONCAT('Oracle', ' Server')
 → Oracle Server 
 SUBSTR(
문자값,  a,  b)
 a 
선택할 문자열의 시작위치.
 
음수면 끝에서부터 시작
 b 
선택할 문자열의 개수.
 
 인자는 생략할  있으며,  
 
생략할 경우 문자열의 끝까지 선택 
 :  SUBSTR('
강남구 역삼동‘,5,2)
 → 
역삼 
 LENGTH(
문자값1, a, 문자값2) : LENGTH(‘홍길동’)
 → 3 
 LPAD(
문자값1, a, 문자값2)
 RPAD(
문자값1, a, 문자값2)
 a : 
전체 채울 자리수
 
문자값2 : 채울 문자 
 
생략할  있으며생략되면 
 
공백값임 
 : LPAD(‘
홍길동’,10 ‘*’)
 → ****
홍길동 
 LTRIM(
문자값1, 문자값2)
 RTRIM(
문자값1, 문자값2)
 
문자값1에서 왼쪽(오른쪽)에서부터
 
더이상 문자값2 만나지 않을 때까지 지움
 : LTRIM('XXAXBA','X')
 → AXBA 
 TRANSLATE(
문자값, a, b)
 a 
대체하고 싶은 문자(from)
 b 
대체할 결과의 문자(to) 
 : TRANSLATE('AABBA','B','C')
 → AACCA 
 REPLACE (
문자값, a, b) 
 a 
바꾸고 싶은 문자(from)
 b 
바꿀 결과의 문자(to) 
 : REPLACE ('JACK and JUE','J','BL') 
 → BLACK and BLUE 

 - 
숫자형 함수
 ROUND : 
숫자를 반올림 
 TRUNC : 
숫자를 절사 
 MOD : 
나누기 연산에서 나머지 구함 
 POWER : 
거듭제곱 
 SQRT : 
제곱근 
 SIGN : 
양수인지 음수인지 0인지를 구벌함 
 CHR : ASCII 
값에 해당하는 문자를 구함 

 ROUND(
숫자값, a), TRUNC(숫자값, a)
 a 
숫자값을 반올림(버림)하여 a자리까지 
 
돌려줌.a 양수이면 소수이하자리를
 
음수이면 정수 부분 자리임
 
생략할  있으며생략하면 0
 : ROUND(35.735,2)→35.74 
 MOD(
숫자값, a )
 a 
숫자값을 나누기   있음
 : MOD(7,2)→1 
 POWER(
숫자값1, 숫자값2) : POWER(3,2)→9 
 SQRT (
숫자값) : SQRT(25)→5 
 SIGN(
숫자값) : SIGN(-15)→-1 
 CHR(
숫자값) : CHR(65)→A 

 - 
날짜형 함수
 SYSDATE : 
현재 시스템의 날짜  시간을 구함 
 LAST_DAY : 
지정한 날짜의 해당 월의 마지막 날짜를 구함 
 MONTHS_BETWEEN : 
 날짜 사이의 개월 수를 구함 
 ADD_MONTHS : 
지정한 날짜로부터  개월 후의 날짜를 구함 
 ROUND : 
날짜에 대한 반올림 
 TRUNC : 
날짜에 대한 버림 

 SYSDATE : SYSDATE → 10-MAY-99 
 LAST_DAY(
날짜값) : LAST_DAY('17-FEB-98') → 28-FEB-98 
 MONTHS_BETWEEN(
날짜값1, 날짜값2) : MONTHS_BETWEEN('26-APR-97','22-JUL-95') → 21.1290323
 ADD_MONTHS(
날짜값숫자값) : ADD_MONTHS('22-JUL-95',21) → 22-APR-97 
 ROUND(
날짜값자리수) : 현재 날짜가 1999 5 10일이라고 가정하자.
 ROUND(SYSDATE,'MONTH') → 01-MAY-99
 TRUNC(
날짜값자리수) : 현재 날짜가 1999 5 10일이라고 가정하자.
 TRUNC(SYSDATE,'YEAR') → 01-JAN-99

 - 
날짜에 대한 산술연산
 
날짜 + 숫자 : 날짜 특정한 날로부터 몇일 후의 날짜 계산 
 
날짜 - 숫자 : 날짜 특정한 날로부터 몇일 전의 날짜 계산 
 
날짜 - 날짜 : 숫자  날짜 사이의 차이를 숫자로 계산 

 - 
변환형 함수
 TO_CHAR : 
숫자나 날짜를 문자열로 변환 
 TO_NUMBER : 
문자를 숫자로 변환 
 TO_DATE : 
문자를 날짜로 변환 

 - TO_CHAR
에서 숫자를 문자로 변환시에 형식에 사용되는 요소
 9 : 
일반적인 숫자를 나타냄 
 0 : 
앞의 빈자리를 0으로 채움 
 $ : dollar
 표시함 
 L : 
지역 통화 단위(ex ) 
 . : 
소숫점을 표시함 
 , : 
천단위를 표시함 
 - TO_CHAR
에서 날짜를 문자로 변환시에 형식에 사용되는 요소
 SCC : 
세기를 표시 S 기원전(BC) 
 YEAR : 
연도를 알파벳으로 spelling 
 YYYY : 4
자리 연도로 표시 
 YY : 
끝의 2자리 연도로 표시 
 MONTH : 
월을 알파벳으로 spelling 
 MON : 
월의 알파벳 약어 
 MM : 
월을 2자리 숫자로 표시 
 DAY : 
일에 해당하는 요일 
 DY : 
일에 해당하는 요일의 약어 
 DDD,DD,D : 
연도,, 중의 날짜를 숫자로 표시 
 HH , HH24 : (1-12) , (0-23)
중의 시간을 표시 
 MI : 
분을 표시 
 SS : 
초를 표시 
 AM(A.M.),PM(P.M.) : 
오전인지 오후인지를 표시 

 TO_CHAR(
문자값,‘형식’)
 
숫자를 문자로 변환 : TO_CHAR(350000,'$999, 999')→ $350,000
 
숫자를 날짜로 변환 : TO_CHAR(SYSDATE,'YY/MM/DD')→ 95/05/25 
 TO_DATE(
문자값, ‘형식’) : TO_DATE('10 SEPTEMBER 1992','DD MONTH YYYY')→10-SEP-92 
 TO_NUMBER(
문자값) : TO_NUMBER('1234')→ 1234 

 - DECODE 
함수
 DECODE 
함수는 값을 비교하여 해당하는 값을 돌려주는 함수
 > DECODE (
형식,비교값1,결과치1,비교값2,결과치2,...기본치 )
 
형식 : 컬럼이나  
 
비교값1 : 형식이 비교값1 맞는지를 비교 
 
결과값1 : 형식이 비교값1 맞을  갖는  
 
기본치 : 형식이 비교값1,2,... 맞지 않을  가지는 
 
생략될  있으며생략되면 NULL이다

 SQL> SELECT name,title,DECODE(SUBSTR(title,-2,2),
 2 '
부장',salary*1.1,
 3 '
과장',salary*1.07,
 4 '
사원',salary*1.05,
 5 salary) 
이번달급여
 6 FROM s_emp
 7 ORDER BY 3 DESC ;

다중행 함수

 - 
그룹함수
 COUNT( a ) : a
 행의 개수를 구함 
 AVG( a ) : a
 평균을 구함 
 SUM( a ) : a
 합계를 구함 
 MIN( a ) : a
 최소값을 구함 
 MAX( a ) : a
 최대값을 구함 
 STDDEV( a ) : a
 표준 편차를 구함 
 VARIANCE( a ) : a
 분산을 구함 

 COUNT(*)
 제외한 모든 그룹함수는 NULL값을 고려하지 않습니다
 
중복값을 제거하고 싶은 경우는 a 앞에 DISTINCT 기술합니다
 MAX , MIN , COUNT
 제외한 그룹함수는 숫자타입의 데이터에만 가능합니다