posted by 방랑군 2010. 3. 12. 13:01

DDL(Data Definition Language) 은 데이터베이스의 스키마 객체를 생성(CREATE),

 

변경(ALTER), 제거(DROP) 하거나 권한의 부여나 박탈(GRANT, REVOKE), 주석(COMMENT),

 

자료의 버림(TRUNCATE) 등을 수행하는 문장의 집단을 의미한다.

 

각 문장은 CREATE, ALTER, DROP, TRUNCATE, GRANT, REVOKE, COMMENT 등으로 시작한다.

 

이 밖에도 많은 종류의 DDL이 존재한다. 그러나 PL/SQL 블록에서는 DDL을 사용할 수 없다.

 

 

DML(Data Manipulation Language)은 스키마 객체의 데이터를 입력(INSERT), 수정(UPDATE),

[Manipulation=교묘한처리,조종]

 

조회(SELECT), 삭제(DELETE)하거나 테이블에 잠금을 설정하거나 (LOCK TABLE), SQL문의

 

처리의 절차에 대한 정보를 얻거나 (EXPLAIN PLAN), PL/SQL 모듈을 호출하는 작업(CALL)의 집단이다.

 

각 문장은 INSERT, UPDATE, DELETE, SELECT, LOCK TABLE, EXPLAIN PLAN, CALL 등으로 시작된다.

 

PL/SQL의 모듈에서 사용할 수 없는 DML로서는 EXPLAIN PLAN과 CALL이 있다.

 

DCL(Data Control Language)은 트랜잭션의 성격을 제어하는 것으로서 SET TRANSACTION,

 

COMMIT, ROLLBACK, SAVEPOINT와 같은 종류가 있다.

 

PL/SQL 모듈에서는 DCL을 사용할 수 있고 DCL을 이용하여 모듈의 트랜잭션을 제어 할 수 있다.

 

 

발췌 about Oracle 9i PL/SQL  p156   저자 이태윤

posted by 방랑군 2010. 2. 26. 16:09

문자열 함수

Function

Oracle

SQL Server

Convert character to ASCII

ASCII

ASCII

String concatenate

CONCAT

(expression + expression)

Convert ASCII to character

CHR

CHAR

Return starting point of character in character string (from left)

INSTR

CHARINDEX

Convert characters to lowercase

LOWER

LOWER

Convert characters to uppercase

UPPER

UPPER

Pad left side of character string

LPAD

N/A

Remove leading blank spaces

LTRIM

LTRIM

Remove trailing blank spaces

RTRIM

RTRIM

Starting point of pattern in character string

INSTR

PATINDEX

Repeat character string multiple times

RPAD

REPLICATE

Phonetic representation of character string

SOUNDEX

SOUNDEX

String of repeated spaces

RPAD

SPACE

Character data converted from numeric data

TO_CHAR

STR

Substring

SUBSTR

SUBSTRING

Replace characters

REPLACE

STUFF

Capitalize first letter of each word in string

INITCAP

N/A

Translate character string

TRANSLATE

N/A

Length of character string

LENGTH

DATALENGTH or LEN

Greatest character string in list

GREATEST

N/A

Least character string in list

LEAST

N/A

Convert string if NULL

NVL

ISNULL

 

Date 함수

Function

Oracle

SQL Server

Date addition

(use +)

DATEADD

Date subtraction

(use -)

DATEDIFF

Last day of month

LAST_DAY

N/A

Time zone conversion

NEW_TIME

N/A

First weekday after date

NEXT_DAY

N/A

Convert date to string

TO_CHAR

DATENAME

Convert date to number

TO_NUMBER(TO_CHAR())

DATEPART

Convert string to date

TO_DATE

CAST

Get current date and time

SYSDATE

GETDATE()

 

posted by 방랑군 2009. 12. 8. 12:55
1) 단순 버전 확인
SELECT @@VERSION;

@@VERSION : 현재 설치되어 있는 MS SQL Server의 날짜, 버전, 프로세스 유형을 반환 

2) 서비스 팩 확인

select SERVERPROPERTY('productlevel')

3) 버전, 서비스팩, 설치 Edition 확인 

SELECT 'SQL Server ' 
+ CAST(SERVERPROPERTY('productversion') AS VARCHAR) + ' - ' 
+ CAST(SERVERPROPERTY('productlevel') AS VARCHAR) + ' (' 
+ CAST(SERVERPROPERTY('edition') AS VARCHAR) + ')'

그 외,

USE MASTER

GO

 

EXEC XP_MSVER 

 

EXEC XP_MSVER 'PRODUCTNAME', 'PRODUCTVERSION', 'LANGUAGE', 'PLATFORM', 'WINDOWSVERSION', 'PHYSICALMEMORY', 'PROCESSORCOUNT'

'IT > DB' 카테고리의 다른 글

DDL, DML, DCL  (0) 2010.03.12
Oracle과 MSSQL함수 비교  (0) 2010.02.26
#2784A Microsoft SQL Server 2005 튜닝 및 쿼리 최적화  (0) 2009.09.30
데이터 결합 방법 정리  (0) 2009.09.30
MS-SQL 조인 내부 처리 방식 정리  (0) 2009.09.30
posted by 방랑군 2009. 9. 30. 14:10



올해 초에 웹타임 교육센터에서 교육을 받은 내용을 나름대로 정리한 내용이다.

내용은 많고 시간은 부족(?)해서 설명 부분이 많이 부족하다.

그래서 버전은 0.9이다.. +_+

차후에 보완 수정하여 더욱 더 유용한(?) 자료로 거듭났으면 좋겠다 ㅋ

posted by 방랑군 2009. 9. 30. 14:04

참조 :http://elky.tistory.com/215

1 . 데이터의 결합방법

1) 가로로 연결 : JOIN

     - 의미 있는 연결을 위해서는 로우(ROW)의 공통 요소를 이용하여 연결할 경우 사용

2) 세로로 연결 : UNION

     - 컬럼(Colum)의 공통된 형식을 어기면 연결 불가

2 . JOIN

가로(수평적)로 하나의 결과 집합과 다른 결과 집합을 연결하는 것

(집합 : 테이블, 뷰, 인라인뷰, 테이블변수....)

조인의 종류

 ◎ INNER JOIN

 ◎ OUTER JOIN (LEFT , RIGHT 모두)

 ◎ FULL JOIN

 ◎ CROSS JOIN

 ◎ SELF JOIN

1) INNER JOIN

 두 집합간의 하나나 그 이상의 공통 필드들에 기반해서 레코드들을 일치

 INNER JOIN 은 배타적(exclusive) 결합 이다.

 두 집합(테이블) 모두에서 일치하는 것이 없으면 그 레코드는 반환되지 않는다.

 ▷ 구문

<ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> INNER JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

 SELECT <선택_목록>

 FROM <결과집합1> JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 ▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d JOIN stores s

                               ON d.stor_id = s.stor_id

1) OUTER JOIN

JOIN 이전에 나오는 테이블은 왼쪽(LEFT) 테이블이 되고 , JOIN 이후에 나오는 테이블이 오른쪽(RIGHT) 테이블이 된다.

LEFT OUTER JOIN 은 왼쪽 테이블로부터 모든 정보를 포함시키며

RIGHT OUTER JOIN 은 오른쪽 테이블로부터 모든 정보를 포함시킨다

 ▷ 구문

 <ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> LEFT OUTER JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> *= <결과집합2>.<조인조건2>

 <ANSI>

SELECT <선택_목록>

 FROM <결과집합1> RIGHT OUTER JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> =* <결과집합2>.<조인조건2>

 

▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d LEFT OUTER JOIN stores s

                               ON d.stor_id = s.stor_id

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d RIGHT OUTER JOIN stores s

                               ON d.stor_id = s.stor_id

 

※ OUTER JOIN 을 이용하여 일치하지 않는 레코드들 찾기

-- 할인 레코드를 가지지 않은 모든 상점들의 이름 찾기

 

       USE Pubs

       SELECT s.stor_name AS [Store Name]

       FROM discounts d RIGHT OUTER JOIN stores s

                               ON d.stor_id = s.stor_id

       WHERE d.stor_id IS NULL

3) FULL JOIN

JOIN 양쪽의 데이터를 모두 일치 시켜서 양쪽 모두를 포함시키는 것이다.

어느쪽에도 중점을 두지 않고 양쪽 모두의 데이터를 보려 할 때를 위하여 만들어진 것

간단히 FULL JOIN 은 RIGHT JOIN 과 LEFT JOIN 을 동시에 적용하는 것이라 할 수 있다.

 ▷ 구문

<ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> FULL JOIN <결과집합2>  ON <결과집합1>.<조인조건1>=<결과집합2>.<조인조건2>

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> *= <결과집합2>.<조인조건2>

 UNION

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2>  WHERE <결과집합1>.<조인조건1> =* <결과집합2>.<조인조건2>

▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d FULL JOIN stores s

                               ON d.stor_id = s.stor_id

4) CROSS JOIN

한쪽의 모든 레코드를 그 반대쪽의 모든 레코드들과 결합시킨다.

간단히 CROSS JOIN 은 '데카르트의 곱(Cartesian product)' 이라 할수 있다

CROSS JOIN 의 구문 구조는 ON 연산자가 없다는 점만 빼고는 다른 JOIN 들과 동일하다.

테스트용 데이터를 만드는 용도로 사용한다.

 ▷ 구문

<ANSI>

 SELECT <선택_목록>

 FROM <결과집합1> CROSS JOIN <결과집합2> 

 

<T-SQL>

 SELECT <선택_목록>

 FROM <결과집합1> ,<결과집합2> 

▷ 예제

       USE Pubs

       SELECT discounttype ,discount ,s.stor_name

       FROM discounts d CROSS JOIN stores s

5) SELF JOIN

필요에 의해 JOIN 구문에 같은 테이블이 두번 이상 등장하는 경우이다.

 

자신의 상급자를 매핑하기위해 SELF 조인을 사용한 예제이다.

▷ 예제

       USE Northwind

       SELECT a.EmployeeID, a.LastName, a.FirstName, b.EmployeeID, b.LastName, b.FirstName

       FROM employees a, employees b

       WHERE a.reportsTo = b.employeeid

2 . UNION

2개이상의 데이터 집합을 세로(수직적)로 연결하는 방법으로

결합되는 각 컬럼간의 형식이 일치하면 하나의 집합으로 도출 가능하다.

 

▷ 주의점

 ◎ UNION 으로 쿼리들을 결합할 때, 모든 쿼리들의 SELECT 목록에 있는 열들의 개수는 같아야 한다.

 ◎ 결합된 결과의 제일 처음에 나타날 헤더들은 오직 첫번째 쿼리에 의해서만 결합된다.

 ◎ 결합될 쿼리들의 각 열들은 동일한 데이터 형식이거나 적어도 묵시적으로 변환될 수 있는 것들이어야 한다.

 ◎ UNION 의 경우 기본적으로 DISTINCT 가 적용된다. 중복된 행을 표시하고 싶들떄는 UNION ALL 을 사용한다.

 

Northwind 에 관련된 모든사람에게 우편물을 보내고자 할 때의 UNION 을 통해 모든 사람의 주소를 가져오는 쿼리

▷ 예제

       USE Northwind

 

       SELECT CompanyName as Name, Address, City, Region, PostalCode, Country

       FROM Customers

       UNION

       SELECT CompanyName , Address, City, Region, PostalCode, Country

       FROM Suppliers

       UNION

       SELECT FirstName + ' ' + LastName , Address, City, Region, PostalCode, Country

       FROM Employees

 
3 . 요약

RDBMS 에서는 데이터를 둘 이상의 테이블에 분산시켜야 하는 경우가 많다.

따라서 JOIN 및 UNION 을 이용하여 여러 테이블들의 있는 데이터를 결합시켜 사용 할 수 있다.

 ◎ 일치하지 않는 열들을 제외하고자 할 경우에는 INNER JOIN 을 사용한다.

 ◎ 일치하는 것들을 뽑아야 할 뿐만 아니라, JOIN의 한 쪽에 있는 테이블의 모든 것들을 포함시키려 할 때는 OUTER JOIN 을 사용한다.

 ◎ 일치하는 것들을 뽑아야 할 뿐만 아니라, 양쪽에 있는 테이블의 모든 것들을 포함시키려 할 때는 FULL JOIN 을 사용한다.

 ◎ 두 테이블의 대해 행들에 기반한 데카르트 곱을 수행하려 할 때에는 CROSS JOIN 을 사용한다. 과학계산이 필요하거나 테스트 데이터를 생성할때 유용하다.

 ◎ 여러 쿼리들의 결과를 수직적으로 결합할 때에는 UNION 을 사용한다.

posted by 방랑군 2009. 9. 30. 14:03

참조 : http://elky.tistory.com/214


용어 정리
Driving Table : 조인에서 기준이 되는 테이블 (= Outer Table)
Drived Table : 조인에서 결합 되어지는 테이블 (= Inner Table)

Nested Loop
- 두개 이상의 테이블에서, 하나의 집합을 기준으로 상대방 테이블의 Row를 결합하여 원하는 결과를 추출하는 방식. (기준 테이블 한 행당, 상대 테이블 전체가 수행된다.)
- 부분 범위 처리 가능 (정지, 재개 가능. 예를 들어 조건에 만족하는 데이터 1000개만 얻어낸 상태에서, 요청이 들어올경우 1001~2000번째 값을 얻어오는 것이 가능)
- Driving Table에서 상대 테이블로 비교할 데이터 량이 적은 것이 효율에 좋다.
- 기준 테이블과 상대 테이블 간에 서로 대응하는 값에 인덱스가 걸려있는 것이 효율에 좋다.
- 특정 범위만 알아오는 쿼리에 유용.
- Any Join에서 사용 됨.

Sort Merge
- 쿼리에 따라 기준 테이블, 상대 테이블 각각 조인에 포함될 데이터들만 추려내 테이블로 구성한 후 (집합을 구성), 추린 테이블의 데이터를 정렬한다.
(상황에 따라 테이블 전체를 정렬해서 사용하는 경우도 있다.)
- 두 테이블의 크기가 다를 경우, 유후 시간 발생 (정렬 되는 시간이 동일하지 않기 때문에)
- 지그 재그 계단식 비교 방식을 취함 (읽고 있는 데이터 포인터를 기억한 후, 다음 데이터를 읽을 때 이미 읽은 위치를 다시 읽지 않는 방식으로 검색량을 줄인다.)
- 지그 재그 계단식 비교를 하기에, 겹치는 값이 존재할 경우 이미 읽은 데이터를 다시 읽어야 되는 상황이 발생하기도 한다. (같은 값이 여러개일 경우, 방금 읽었던 값도 또 읽어야 하기에) 그래서, 겹치는 값이 존재할 경우 DBMS가 Hash Join을 사용할 가능성이 높다.
- 추려진 결과가 한번에 나오고, 그 전에는 결과를 낼 수 없기에, 처리 속도가 중요한 쿼리에서는 사용되지 않는다.
- Any Join 에서 가능 하지만 주로 Equal Join 에서 유용.

Hash

- 테이블 내의 모든 데이터에 해시 함수를 적용하여 해시 버킷에 담는다. 값 별로 버킷에 나누어 담기에, 해당 버킷을 읽음으로써 같은 값을 사용하는 집합에 억세스. (버킷에 담긴 데이터를 연속으로 읽을 수 있으므로)
- 해시 테이블 구성 비용 (CPU, 메모리)이 크다.
- 값 별로 버킷에 담기기에 버킷 억세스는 같은 값을 찾는 경우에만 빠르다. 그래서, Equal Join 에서만 가능하도록 되어있다.

posted by 방랑군 2009. 9. 30. 14:02
참조 :http://elky.tistory.com/212

1. Clustered Index만 존재했을 때
CI의 정렬 기준으로 실제 데이터를 정렬해 둡니다. 데이터를 찾을 때 CI를 타느냐, 테이블 스캔 하느냐의 차이만 존재합니다. 

1-2. 구조
루트페이지와 리프페이지의 2중 구조

루트페이지에는  검색기준이  리프페이지에는 실제 데이터가 검색기준에 맞쳐 분류되어있음

쿼리시  루트 페이지에서 해당 검색기준을 통해 리프페이지(실제데이터)를 검색하여 결과처리

데이터 변경작업시 루트페이지에 맞쳐서  리프페이지를 다시 분류작업함

2.
Non-Clustered Index만 존재했을 때

이 경우 NI의 키 값 대로 정렬된 데이터가 존재하고, 키 값에 대응하는 실제 데이터의 주소 (파일, 페이지, 행번호) 를 가집니다.

NI에서의 키 값에 매칭되는 값을 찾은 후, 실제 데이터를 찾아가는 과정만큼의 비용이 필요합니다.
이 비용이 크기 때문에, 일반적으로 NI를 이용해서 찾는 데이터가 전체 데이터의 3~5%이내 일 때만 NI를 이용하고, 그렇지 아닐 경우 테이블 스캔을 합니다.

2-1. 구조
루트페이지와 리프페이지. 실제데이터의 3중구조.

루트페이지에는 검색기준, 리프레이지에는 실제데이터를 참조한 분류 ,실제데이터에는 데이터

select 시에는 3중구조임으로 클러스터형 인텍스보다 비효율적임

그러나. 데이터 변경작업시에는 실제데이터에는 변경이 없음으로 클러스터형 보다 효율적.

3. Non-Clustered Index와 Clustered Index 공존시

이 경우 NI가 실제 데이터의 행번호를 가리키는 것이 아니라, CI의 키 값을 가리킵니다.

장점은 CI가 변경될 때, NI에 적은 영향을 줍니다. (CI로 정렬 되어 있는 만큼, 테이블 중간에 데이터가 끼어들거나 삭제되면 페이지 분할등이 일어나 행번호가 바뀔여지가 있습니다. 행번호가 바뀌어도 행번호가 아니라, CI의 키 값을 가리키기 때문에 NI에 적은 영향만을 주고 데이터를 변경할 수 있게 됩니다.)

3-1. 구조
루트페이지(비클러스터형)  -> 리프페이지 (비클러스터형) ->  루트페이지 (클러스트형) -> 리프페이지 (클러스트형) 의 4중구조 (실제데이터는 리프페이지 - 클러스트형)

'IT > DB' 카테고리의 다른 글

데이터 결합 방법 정리  (0) 2009.09.30
MS-SQL 조인 내부 처리 방식 정리  (0) 2009.09.30
인덱스 정리  (0) 2009.09.30
인덱스가 있지만 인덱스를 안 타는 경우  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
posted by 방랑군 2009. 9. 30. 14:01

참조 : http://elky.tistory.com/211

데이터를 찾는 과정이 필요한 모든 일 (Select, Update, delete, Insert 모두) 에 영향을 준다.

데이터를 빠르게 찾기 위해 필요하다.

인덱스 추가시 인덱스 관리 비용(처리하는 일, 인덱스 관리용 공간 필요)

인덱스는 항상 타는게 아니다. 인덱스를 탈 때 통계를 참고하는데, 이 통계가 최적 수행 방법을 산출하려면, 통계가 최신에 가까워야 좋다.

하지만, 통계 갱신에는 비용이 존재하므로, 적절한 수위를 유지하는 것이 좋다.

인덱스가 걸려 있는 경우에는 정렬이 필요하다.  1Page가 꽉 찬 상태에서, 데이터가 중간 삽입 될 경우, 들어갈 데이터를 포함해 데이터를 반으로 쪼개서 두개의 페이지에 넣는다. 이 것을 페이지 분할이라 부른다. 

페이지 분할이 자주 일어날꺼라 생각되면 인덱스 생성시 채우기 비율 설정으로, 미리 페이지 분할 해두는 것이 가능하다.

이렇게 할 경우, 페이지를 여러개로 나누는 만큼 페이지를 읽어오는 양이 늘어나는 부담이 생긴다.
검색에 사용된 인덱스가 유니크 인덱스일 경우에는, 데이터를 찾자마자 검색 과정을 중단하면 되기에 검색시에 더 빠르다.

인덱스 검사하는 법
explain select * from Table_Name where A='a' and B='b' order by C,D,E ;
해당 쿼리문이 인덱스를 타는지 안타는지 알기 위해서는 쿼리문 앞에 explain을 붙여주면 인덱스를 타는지 안타는지 알 수 있습니다.
type의 결과값이 ALL일 경우 인덱스를 타지 않고 있습니다. range,index등일 때 인덱스를 타고 있습니다.(system,const,eq_ref,range,index,ALL,fulltext)
key의 값이 해당 쿼리문이 타고 있는 인덱스입니다.


인덱스 관련 용어 정리
-
Table Scan
인덱스를 사용하지 않고 테이블 전체를 읽는것.

- Index Seek
인덱스를 사용해서 데이터를 찾은 것.

- Random Access
 여러 데이터를 찾을 때, 순차적으로 다음행을 읽지 못하고, 데이터 하나당 검색을 수행해야 하는 경우를 말함.

- Clustered Index (CI) 
실제 데이터를 키에 따라 정렬 하는 것이다.
페이지 분할시 실제 데이터도 분할해야 하는 것이 단점이다.
범위 처리에 일반적으로 유용하다. (쿼리에 따라 다르지만)

- Non-Clustered Index (NI) 
키 + 주소로 설정된 별도의 저장소를 가진다.
일반적으로 CI보다 크기가 작으므로, 한 페이지에 많이 들어간다. 데이터 검색시 페이지 간 이동이 CI보다 적다는 장점이 있다.
키에 따라 검색이 끝나도 실제 주소를 찾으러 가야하기 때문에, 범위 처리가 CI보다 느리다.

Covered Query : Index에 포함된 값만 필요로 해서 (a, b컬럼이 복합 인덱스로 걸려 있을 때 select a, b from table), 인덱스만 읽어서 결과를 보여줄 수 있는 쿼리를 말합니다.

posted by 방랑군 2009. 9. 30. 14:01

참조 : http://elky.tistory.com/210

1. 인덱스  컬럼의 변형
select * from table  where LOWER(name)  ='word';
select * from table  where idx - 1 = 5;
이 처럼 인덱스에 변형을 가하게 되면, DBMS가 인덱스를 이용하지 않는다.

2. NOT 또는 IN 연산자 사용
NOT일 경우 무조건 인덱스를 안타는 것이 아니다.
NOT일 경우에도 인덱스를 타긴 타지만, 일반적으로, NOT에 사용된 값이 아닌 데이터의 비율이 높은 경우가 많기 때문에 인덱스를 타지 않는 경우가 많다.
마찬가지로 IN일 경우에도, IN에 포함된 데이터들의 비율이 매우 높다면 FULL SCAN을 하는 것이 낫다고 DBMS가 판단하면 인덱스를 타지 않는다.


3. 와일드 카드 LIKE문장에서 범위를 전체를 지정시
select * from table  where name like '%word'; 
문자열로 이루어진 값을 인덱스로 잡았을 때, %가 앞쪽에 사용되면 정렬 순서를 사용할 수 없으므로 테이블 FULL SCAN이 이루어진다.

select * from table  where name like 'word%'; 
당연한 얘기지만 쿼리가 이런 경우 인덱스를 탄다. 문자열 정렬 순서를 그대로 이용할 수 있기 때문이다.

4. 복합 컬럼 index에서 조건이 잘못되여 index 가 적용 되지 못하는경우
select * from table where name = 'word' or idx = 5

name과 idx가 둘다 인덱스가 걸려있는 경우라해도, DBMS가 최적의 OR 조건을 뽑기 힘들어, FULL SCAN 하는 경우가 많다.

5. Optimizer 의 선택
select * from table  where name ='word' and  id ='elky'; 

인덱스가 name 과   id로 2개가 있을 경우 id나 name 인덱스 중 하나가 선택될수도 있고, 둘다 선택 될 수도있다.
어떤 방식으로 선택하는냐가 속도에 중요할수도있다. 즉 실행 계획을 추적해서 원하는 결과가 나오도록 관리가 필요하다

'IT > DB' 카테고리의 다른 글

한 테이블에 존재하는 인덱스의 종류에 따른 차이  (0) 2009.09.30
인덱스 정리  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
Inline 쿼리 VS 저장 프로시저  (0) 2009.09.30
SUBQUERY와 INLINE-VIEW의 차이  (1) 2009.09.30
posted by 방랑군 2009. 9. 30. 14:00

참조 : http://elky.tistory.com/218


MSSQL에선 실행 계획을 통해 인덱스를 타는지, 어떠한 쿼리가 더 빠른지 측정할 수가 있습니다.

쿼리
Set Statistics Profile { ON | OFF } -- 쿼리 결과에 실행 계획을 포함
Set Statistics IO {ON | OFF}         -- 페이지의 입출력 수를 알 수 있다.
Set Showplan_All { ON | OFF }     -- 실행 계획만 보는 옵션

실행 계획은 SQL Server 쿼리 프로세서가 각 문을 실행할 때 취한 단계를 나타내는 계층적 트리를 이루는 행 집합으로 정보를 반환합니다. 출력에 반영된 문에는 문의 텍스트가 있는 단일 행이 포함되고, 이 단일 행 뒤에는 실행 단계에 대한 자세한 정보가 있는 몇 개의 행이 있습니다 아래 표에서는 출력에 포함된 열을 보여 줍니다.

열 이름

설명

Rows

실행된 행수

Executes

Loop 일 경우 Loop 실행 된 횟수

StmtText

PLAN_ROW 형식이 아닌 행에 대해 이 열에는 Transact-SQL 문의 텍스트가 포함됩니다. PLAN_ROW 유형의 행에 대해서는 이 열에 작업에 대한 설명이 포함됩니다. 이 열에는 물리적 연산자가 포함되며 논리 연산자가 포함될 경우도 있습니다. 이 열 다음에 물리적 연산자가 결정한 설명이 나올 경우도 있습니다. 자세한 내용은 논리 물리 연산자 참조를 참조하십시오.

StmtId

현재 일괄 처리에 있는 문의 수입니다. (몇번째 쿼리에 대한 통계인지)

NodeId

현재 쿼리의 노드 ID입니다. (현재 노드의 식별값)

Parent

부모 단계의 노드 ID입니다 (이 값이 같은 것 끼리, 같은 depth라고 생각하면 된다)

PhysicalOp

노드에 대한 물리적 구현 알고리즘입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

LogicalOp

이 노드가 나타내는 관계형 대수 연산자입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

Argument

수행되는 작업에 대한 추가 정보를 제공합니다. 물리적 연산자에 따라 이 열의 내용이 달라집니다.

DefinedValues

이 연산자가 사용하는 값에 대한 쉼표로 구분된 목록을 포함합니다. 이 값은 현재 쿼리에 있었던 계산된 식(: SELECT 목록이나 WHERE 절에 있음)이거나 이 쿼리를 처리하기 위해 쿼리 프로세서에서 사용한 내부 값입니다. 쿼리 내의 어디에서든 정의된 이 값이 참조될 수 있습니다. PLAN_ROWS 형식의 행에만 해당됩니다.

EstimateRows

이 연산자가 생성한 출력의 예상 행 수입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

EstimateIO

작업에 대한 예상 I/O 비용입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

EstimateCPU

이 연산자에 대한 예상 CPU 비용입니다. PLAN_ROWS 형식의 행에만 해당됩니다.

AvgRowSize

이 연산자를 통해 통과되는 행의 예상 평균 행 크기(바이트)입니다.

TotalSubtreeCost

이 작업 및 모든 자식 작업에 대한 예상(누적) 비용입니다.

OutputList

현재 작업에서 예상하고 있는 열에 대한 쉼표로 구분된 목록을 포함합니다.

Warnings

현재 작업과 연관된 경고 메시지에 대한 쉼표로 구분된 목록을 포함합니다. 경고 메시지에 열 목록과 함께 "NO STATS:()" 문자열이 포함될 경우도 있습니다. 이 경고 메시지는 쿼리 최적화 프로그램이 이 열의 통계에 기초하여 결정을 내리려고 했지만 사용 가능한 통계가 없었음을 나타냅니다. 따라서 쿼리 최적화 프로그램이 추측을 해야 했고 결과적으로 비효율적인 쿼리 계획을 선택했을 수도 있습니다. 쿼리 최적화 프로그램이 더 효율적인 쿼리 계획을 선택할 수 있도록 통계를 만들거나 업데이트하는 방법은 UPDATE STATISTICS를 참조하십시오. 어떤 경우에는 이 열에 조인 조건자 없이 조인(테이블을 수반하는)이 일어났음을 나타내는 "MISSING JOIN PREDICATE" 문자열이 포함되기도 합니다. 실수로 조인 조건자를 삭제하면 예상보다 실행 시간이 긴 쿼리가 만들어지고 큰 결과 집합이 반환됩니다. 이 경고가 나타나면 조인 조건자를 의도적으로 사용하지 않았는지 확인하십시오.

Type

노드 유형. 각 쿼리의 부모 노드에 대해서는 노드 유형이 Transact-SQL 문 유형(: SELECT, INSERT, EXECUTE )입니다. 실행 계획을 나타내는 하위 노드에 대해서는 PLAN_ROW 유형입니다.

Parallel

0 = 연산자가 병렬로 실행되지 않습니다.

1 = 연산자가 병렬로 실행됩니다.

EstimateExecutions

현재 쿼리를 실행하는 동안 이 연산자가 실행될 예상 횟수입니다.



Physical Op & Losical Op 에 사용되는 연산자
1) Bookmark Lookup 실행 계획 연산자
Bookmark Lookup 연산자는 책갈피(행 ID 또는 클러스터링 키)를 사용하여 테이블이나 클러스터형 인덱스에서 해당 행을 조회합니다. Argument 열에는 테이블이나 클러스터형 인덱스에서 행을 조회할 때 사용하는 책갈피 레이블이 포함됩니다. Argument 열에는 행을 조회하는 테이블 또는 클러스터형 인덱스의 이름도 포함됩니다. WITH PREFETCH 절이 Argument 열에 나타나는 경우에 쿼리 프로세서에서는 테이블 또는 클러스터형 인덱스에서 책갈피를 조회할 때 비동기 사전 인출(미리 읽기)을 사용하는 것을 최적의 방법으로 결정합니다.

SQL Server 2008에서는 Bookmark Lookup이 사용되지 않습니다. 대신 Clustered Index Seek 및 RID Lookup이 책갈피 조회 기능을 제공합니다. Key Lookup 연산자도 이 기능을 제공합니다.

Clustered Index는 DATA PAGE가 Index Leaf Level 에 존재를 한다.
Non-Clustered Index의 DATA PAGE는 Index Leaf Level에 존재하지 않는다.

즉, Non-Clustered Index로 해당 값을 Index Seek로 검색을 하였어도 출력될 값을 찾기 위해서는 해당 DATA PAGE 까지 찾아 들어가야 하는것이다. 그래서 MS-SQL 2000에서는 Bookmark lookup이라는것이 발생하는것이다.

2) RID Lookup 실행 계획 연산자
RID Lookup은 제공된 RID(행 식별자)를 사용하여 힙을 조회하는 책갈피 조회입니다. Argument 열은  테이블의 행을 조회하는 데 사용되는 책갈피 레이블 및 행을 조회할 테이블의 이름을 포함합니다.

RID Lookup은 항상 NESTED LOOP JOIN과 함께 사용됩니다.
RID Lookup은 물리 연산자입니다.

이제 RID Lookup을 실제 재현해보기 위해서 Test_Lookup Table에 Unique Non-Clustered Index를 만들어 보겠다.
왜 굳이 Non-Clustered Index를 만드느냐? RID Lookup은 Heap Table에서 만 일어난다. Heap Table은 Clustered Index가 없는 Table을 지칭한다. 그럼 왜 또 구지 Unique Type으로 만드냐? Unique Type이 아니면 Query 실행 될때 Table Scan이 일어난다

3) Key Lookup 실행 계획 연산자
SQL Server 2005 서비스 팩 2에 새로 추가된 Key Lookup 연산자는 클러스터형 인덱스가 있는 테이블의 책갈피 조회입니다. Argument 열에는 클러스터형 인덱스의 이름과 클러스터형 인덱스에서 행을 조회할 때 사용되는 클러스터링 키가 포함됩니다. Key Lookup은 항상 Nested Loops 연산자와 함께 사용됩니다. WITH PREFETCH 절이 Argument 열에 나타나는 경우에 쿼리 프로세서에서는 클러스터형 인덱스에서 책갈피를 조회할 때 비동기 사전 인출(미리 읽기)을 사용하는 것을 최적의 방법으로 결정합니다. 

Table에서 KEY Lookup을 발생시키려면 3가지 조건이 필요하다.
첫번째, Clustered Index가 존재해야 한다.
두번째, 검색될 Non-Clustered Index가 존재해야 한다.
세번째, Index가 걸리지 않은 출력될 목록이 있어야 한다.

posted by 방랑군 2009. 9. 30. 13:37

 저장프로시저가 좋다고 지랄하는 놈들한테 넌지시 말한번 꺼낼수 있는 좋은 아티클..^^;

이분한테 참 감사하고 싶다...

그래도, 나도 싫은 DB 에 잘 몰라서다... 우기기는 싫거든....


참조 : http://resisa.tistory.com/55


"저장 프로시저 사용해보셨나요?" 어떤 분이 저에게 이렇게 묻는다면 저는 "아니요. "라고 대답을 할 것입니다. 안타깝게도(?) 프로젝트에서 전 저장 프로시저를 사용해보지 못했습니다. 그래서 전 저장프로시저에 대해서 잘모릅니다. 이번에는 진짜로 제가 받은 질문입니다. 개발시에 Inline쿼리와 저장 프로시저중에 선택을 해야 한다면 어떤 것을 선택할 것이냐는 질문입니다. 개발인력이 많다면 전 Inline쿼리를 사용할 것이라고 대답했습니다. 개발인력이 많다는 것은 제 개인적인 생각이지만 저처럼 저장 프로시저를 사용해보지 못한 사람들도 많을 것이라는 생각때문이였고 저장 프로시저에 대해서 제 자신이 잘 모르기 때문입니다. 그 분이 다시 저에게 이런 말을 했습니다. 저장 프로시저는 컴파일이 된 이후에 다음에 사용할 경우에는 캐쉬된 상태로 사용되기 때문에 당연히 저장 프로시저를 사용해야 된다는 말이였습니다. 그래서 제가 정적SQL인지 동적SQL인지 명칭이 확실하지는 않지만 파라미터를 사용하는 쿼리는(MSSQL @문자로 오라클은 :문자로 받을 경우) 컴파일을 한번만 한다고 말했지만 그 분은 아니라고 하셨습니다. 그럼 한 번 확인해볼까요?

테스트 환경은 운영체제는 Vista, DB MSSQL2005이며 System.Data.SqlClient를 사용해서 확인해보도록 하겠습니다. 코드는 아래와 같습니다.
1.
파라미터 없는 SQL

string ConnStr = "Data Source=(local);Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=dsdvp";

 

string query = " SELECT * FROM Student WHERE ID = '2' ";

SqlConnection conn = new SqlConnection(ConnStr);

 

SqlCommand cmd = new SqlCommand(query, conn);

conn.Open();

 

cmd.ExecuteNonQuery();

conn.Close();


2. 파라미터 있는 SQL

string ConnStr = "Data Source=(local);Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=dsdvp";

 

string query = " SELECT * FROM Student WHERE ID = @ID ";

SqlConnection conn = new SqlConnection(ConnStr);

 

SqlCommand cmd = new SqlCommand(query, conn);

SqlParameter param = new SqlParameter("ID", "2");

 

cmd.Parameters.Add(param);

conn.Open();

 

cmd.ExecuteNonQuery();

conn.Close();


3. 저장 프로시저

string ConnStr = "Data Source=(local);Initial Catalog=TestDB;Persist Security Info=True;User ID=sa;Password=dsdvp";

SqlConnection conn = new SqlConnection(ConnStr);

 

SqlCommand cmd = new SqlCommand();

cmd.Connection = conn;

cmd.CommandType = CommandType.StoredProcedure;

cmd.CommandText = "TestProc";

conn.Open();

 

cmd.ExecuteNonQuery();

conn.Close();

=> Inline쿼리나 저장 프로시저가 컴파일되는지의 여부를 알기 위해서 이전에 SQL 튜닝교육을 받았던 문서를 보다가 운영체제에서 제공해주는 XP에서는 관리도구-성능 Vista에서는 관리도구-안정성 및 성능모니터를 사용하였습니다. 성능모니터를 하기 위해서는 카운터를 추가해주어야 합니다. SQL Server:SQL Statstics에서 SQL Compilations/sec SQL Re-Complilations/sec를 추가해주고 배율을 좀 더 확인하기 쉽도록 1에서 10으로 변경해준 후에 위의 구문 3개를 실행해보았습니다.
먼저 1, 2, 3번을 차례대로 실행했을 경우의 화면입니다.

=> 파라미터가 없는 SQL이 가장 높게 나타나는 것을 볼 수 있고 파라미터가 있는 SQL과 저장 프로시저를 동일하게 나타납니다. 이후의 1, 2, 3번 어떤 것을 계속 실행하여도 다시 컴파일 되는 것을 볼 수 없습니다. 혹시나 1, 2, 3번을 실행한 순서에 관계가 있나 싶어 서비스에서 SQL를 내렸다 다시 올려 번갈아 가면서 실행해 보았지만 순서만 달라질 뿐 위의 결과와 똑같은 것을 확인할 수 있었습니다. 여기서 Inline쿼리도 저장 프로시저와 마찬가지로 한번만 컴파일 된다는 것을 알 수 있습니다. 저는 2, 3번만 컴파일이 한번 될 줄 알았는데 1번도 컴파일은 한번만 됩니다. 그런데 왜 1번만 컴파일 과정에서 높게 나타날까요? SQL Server Profiler로 알아보도록 하겠습니다.

새추적를 누르고 '모든 이벤트 표시'를 체크해준 후에 Stored Procedures TSQL의 모든 이벤트를 체크해줍니다그리고 1, 2, 3번을 실행시킨 화면입니다.
1.
파라미터 없는 SQL

2. 파라미터 있는 SQL

3. 저장 프로시저

=> 차이가 보이시나요? 1번에서는 SP:CacheInsert가 두 번 되는 것을 확인하실 수 있습니다. 그래서 2번이나 3번보다 컴파일시에 더 높게 나타나는 것입니다. 다음은 컴파일 된 이후에 1번을 실행시킨 것을 추적한 화면입니다.

=> SP:CacheHit가 일어나는 것으로 보아 그냥 날리는 Inline 쿼리의 경우에도 캐쉬가 되는 것을 알 수있습니다. 더군다나 파라미터가 있는 SQL의 경우에는 마치 저장 프로시저처럼 실행이 되는 것도 알 수 있었습니다컴파일도 캐쉬도 Inline쿼리가 저장 프로시저보다 사용하기에 나쁜 이유는 되지 않는 것 같습니다.

다음은 제가 SQL 튜닝 교육을 받았던 강사님의 홈페이지에 대한 저장 프로시저에 대한 내용입니다.
http://www.sqlworld.pe.kr/

1. 저장 프로시져에 사용된 모든 구문이 미리 분석되어 최적화된 후 처음 수행시 메모리에 올려져 이후에 사용 될때는 메모리에 올려진 내용이 수행되므로 속도가 월등히 빠릅니다.
2. 복잡한 퀴리문을 네트워크를 통하여 서버로 보낼 필요가 없이, 단지 저장 프로시져를 호출하는 간단한 내용만 서버로 전달되므로 네트워크 트래픽이 감소됩니다.
3. 특정 테이블에 대한 권한이 없는 사용자 계정에 저장 프로시져를 수행 할 수 있는 권한을 주어 필요한 작업을 할 수있게 할 수 있으므로 보안성을 높일 수 있습니다.
4. 특정 기능을 수행하는 저장 프로시져를 만들어 두면 여러 응용프로그램에서 이를 활용 할 수 있습니다. , 특정처리를 위한 모듈화작업이 가능합니다. 모듈화가 되어 있으므로 응용프로그램 전체의 수정없이 해당 저장 프로시져만을 수정하여 원하는 기능 구현을 할수 있습니다.

=> 1번의 경우 월등히 빠르다는 위에서 제가 테스트한 결과와 조금은 다른 내용으로 저에게 질문을 하신 분과 같은 의견입니다. 2번의 경우가 제가 표현을 못했던 가장 중요한 이유입니다. 복잡한 쿼리문을 네트워크로 전송하는 것보다는 저장 프로시저의 이름만 넘기는 것이 당연히 네트워크의 부하를 주지 않을 것입니다하지만 이 경우도 일반적인 응용 프로그램이 아닌 웹 프로그램이면서 웹서버와 DB가 같이 돌고 있는 경우라면 그렇게 큰 차이가 있을까요? 3번의 경우에는 응용 프로그램 자체에서 권한 관리를 한다면 굳이 상관없어 보입니다. 4번이 인라인과 저장 프로시저를 어떤 것을 선택해야 하는지의 가장 중요한 지표가 되는 것 같습니다. 쿼리 부분을 프로그램에서 관리할 것인지 DB안에 저장 프로시저로 관리할 것인지의 여부입니다.

일반적으로 비지니스 로직 레이어에서 트랜잭션을 발생시킵니다. 저장 프로시저를 사용하면 저장 프로시저안에서 트랜잭션 처리를 하게 되고 실질적으로 비지니스 로직 레이어가 의미가 없어져 버립니다. 하지만 이 트랜잭션이라는 것이 단순히 DB에 대한 트랜잭션만 있어야 하는 것일까요? 파일이나 레지스트리에 대한 모든 것에 트랜잭션으로 한꺼번에 처리하고 싶을 경우에도 저장 프로시저로 모든 것이 가능할까란 생각이 제일 먼저 듭니다. 또한 비지니스 로직에 계산 로직 등 복잡한 로직이 들어간 상태에서 트랜잭션 처리를 해야 한다면 저장 프로시저에서는 어떻게 처리할까요다시 한번 말씀드리지만 저는 저장 프로시저를 싫어하는 사람이 아니라 저장 프로시저에 대해서 잘 모르는 사람입니다. 아마 정답은 상황에 맞게 Inline쿼리와 저장 프로시저를 적절하게(?) 사용하는 것 아닐까요?

저작자 표시



'IT > DB' 카테고리의 다른 글

인덱스 정리  (0) 2009.09.30
인덱스가 있지만 인덱스를 안 타는 경우  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
SUBQUERY와 INLINE-VIEW의 차이  (1) 2009.09.30
[MS SQL] ldf 파일 사이즈 줄이기 또는 삭제하기  (0) 2009.09.28
posted by 방랑군 2009. 9. 30. 13:31

참조 : http://blog.naver.com/addibuddi?Redirect=Log&logNo=16037753


SUBQUERY와 INLINE-VIEW가 표현되는 방식이 달라....

의미상으로도 다른줄 알았는데...

INLINE-VIEW자체도 SUBQUERY의 하나의 방식이라는 군요..

 

및에는 참조~

 


☞ Subquery란?  
 
 ◈ SUBQUERY는 다른 하나의 SQL 문장의 절에 NESTEDED된 SELECT 문장 입니다.

 ◈ SELECT, UPDATE, DELETE, INSERT와 같은 DML문과 CREATE TABLE 또는 VIEW에서
     이용 될 수 있습니다.

 ◈ 알려지지 않은 조건에 근거한 값들을 검색하는 SELECT 문장을 작성하는데 유용 합니다.

 ◈ SUBQUERY는 MAIN QUERY가 실행되기 이전에 한번 실행 됩니다.


☞ Guidelines

 ◈ SUBQUERY는 괄호로 묶어야 합니다.

 ◈ 두 종류의 비교 연산자들이 SUBQUERY에 사용 됩니다.
    - 단일 행 연산자( =,>, >=, <, <=, <>, != )
    - 복수 행 연산자( IN, NOT IN, ANY, ALL, EXISTS )

 ◈ SUBQUERY는 연산자의 오른쪽에 나타나야 합니다.


☞ SUBQUERY의 유형
 
 ◈ 단일 행(Sing-Row) 서브쿼리 : SELECT문장으로부터 오직 하나의 행만을 검색하는 질의입니다

 ◈ 다중 행(Multiple-Row) 서브쿼리 : SELECT문장으로부터 하나 이상의 행을 검색하는 질의입니다

 ◈ 다중 열(Multiple-Column) 서브쿼리 : SELECT문장으로부터 하나 이상의 컬럼을 검색하는
    질의입니다

 ◈ FROM절상의 서브쿼리(INLINE VIEW) : FROM절상에 오는 서브쿼리로 VIEW처럼 작용 합니다.

 ◈ 상관관계 서브 쿼리 : 바깥쪽 쿼리의 컬럼 중의 하나가 안쪽 서브쿼리의 조건에 이용되는
     처리 방식 입니다.


☞ FROM절상의 서브쿼리(INLINE VIEW)

 ◈ SUBQUERY는 FROM절에서도 사용이 가능 합니다.

 ◈ INLINE VIEW란 FROM절상에 오는 서브쿼리로 VIEW처럼 작용 합니다.

 
예제)급여가 20부서의 평균 급여보다 크고 사원을 관리하는 사원으로서 20부서에 속하지 않은
      사원의 정보를 보여주는 SQL문 입니다.
 
SQL>SELECT b.empno,b.ename,b.job,b.sal, b.deptno
        FROM (SELECT empno
                  FROM emp  
                  WHERE sal >(SELECT AVG(sal) FROM emp WHERE deptno = 20))
a, emp b
        WHERE a.empno = b.empno
             AND b.mgr is NOT NULL
            AND b.deptno != 20
 
     EMPNO ENAME      JOB              SAL     DEPTNO
---------- ---------- --------- ---------- ----------
      7698 BLAKE      MANAGER         2850         30
      7782 CLARK      MANAGER         2450         10

 

 


☞ 다중 열(Multiple-Column) 서브쿼리

 ◈ 다중 열 서브쿼리란 서브쿼리의 결과값이 두개 이상의 컬럼을 반환하는 서브쿼리 입니다.


☞ Pairwise(쌍비교) Subquery
 
 - 서브쿼리가 한번 실행되면서 모든 조건을 검색해서 주 쿼리로 넘겨 줍니다.
 
SQL> SELECT empno, sal, deptno
        FROM emp
        WHERE (sal, deptno) IN ( SELECT sal, deptno
                                            FROM emp
                                            WHERE deptno = 30
                                                 AND comm is NOT NULL )
;
                             
     EMPNO        SAL     DEPTNO
---------- ---------- ----------
      7521       1250         30
      7654       1250         30
      7844       1500         30
      7499       1600         30



☞ Nonpairwise(비쌍비교) Subquery

 - 서브쿼리가 여러 조건별로 사용 되어서 결과값을 주 쿼리로 넘겨 줍니다.
 
SQL>SELECT empno, sal, deptno
        FROM emp
        WHERE sal IN ( SELECT sal
                              FROM emp
                              WHERE deptno = 30
                                   AND comm is NOT NULL )

            AND deptno  IN ( SELECT deptno
                                    FROM emp
                                    WHERE deptno = 30
                                         AND comm is NOT NULL );


     EMPNO        SAL     DEPTNO
---------- ---------- ----------
      7521       1250         30
      7654       1250         30
      7844       1500         30
      7499       1600         30



☞ Null Values in a Subquery

   - 서브쿼리에서 null값이 반환되면 주 쿼리 에서는 어떠한 행도 반환되지 않습니다.

 

☞ 다중 행(Multiple-Row) 서브쿼리

 ◈ 하나 이상의 행을 RETURN하는 SUBQUERY를 다중 행 SUBQUERY라고 합니다.

 ◈ 복수 행 연산자(IN, NOT IN, ANY, ALL, EXISTS)를 사용 할 수 있습니다.


☞ IN 연산자의 사용 예제
 
  부서별로 가장 급여를 많이 받는 사원의 정보를 출력하는 예제
 
SQL>SELECT empno,ename,sal,deptno  
        FROM emp
        WHERE sal IN (SELECT MAX(sal)
                              FROM emp
                              GROUP BY deptno)
;

     EMPNO ENAME             SAL     DEPTNO
---------- ----------   ---------- ----------
      7698 BLAKE             2850           30
      7788 SCOTT            3000           20
      7902 FORD              3000           20
      7839 KING               5000           10



☞ ANY 연산자의 사용 예제

  ANY연산자는 서브쿼리의 결과값중 어느 하나의 값이라도 만족이 되면 결과값을 반환 합니다.

SQL>SELECT ename, sal
        FROM emp
        WHERE deptno != 20
             AND sal > ANY(SELECT sal FROM emp WHERE job='SALESMAN');  
 
ENAME             SAL
---------- ----------
ALLEN            1600
BLAKE            2850
CLARK            2450
KING              5000
TURNER          1500
MILLER           1300

6 개의 행이 선택되었습니다.



☞ ALL 연산자의 사용 예제

  ALL연산자는 서브쿼리의 결과값중 모든 결과 값이 만족 되야만 결과값을 반환 합니다.
 
SQL>SELECT ename, sal
        FROM emp
        WHERE deptno != 20
             AND sal > ALL(SELECT sal FROM emp WHERE job='SALESMAN');
 
ENAME             SAL
---------- ----------
BLAKE            2850
CLARK            2450
KING             5000

3 개의 행이 선택되었습니다.



☞ EXISTS 연산자의 사용 예제

 - EXISTS 연산자를 사용하면 서브쿼리의 데이터가 존재하는가의 여부를 먼저 따져 존재하는
   값들만을 결과로 반환해 줍니다.
 - SUBQUERY에서 적어도 1개의 행을 RETURN하면 논리식은 참이고 그렇지 않으면 거짓 입니다.

예제)사원을 관리할 수 있는 사원의 정보를 보여 줍니다.
 
SQL>SELECT empno, ename, sal
        FROM emp e
        WHERE EXISTS (SELECT empno FROM emp WHERE e.empno = mgr) 

     EMPNO ENAME             SAL
---------- ---------- ----------
      7566 JONES             2975
      7698 BLAKE             2850
      7782 CLARK             2450
      7788 SCOTT            3000
      7839 KING               5000
      7902 FORD              3000
 
6 개의 행이 선택되었습니다.

  ================================================
    * Oracle Community OracleClub.com
    * http://www.oracleclub.com
    * http://www.oramaster.net
    * 운영자 : 김정식 (oramaster _at_ empal.com)
  ================================================ 



posted by 방랑군 2009. 9. 28. 08:54

Mssql의 로그파일인 LDF파일이 너무 커져버렸을때 용량 줄이기 방법

backup log 데이터베이스이름 with TRUNCATE_ONLY

DBCC SHRINKFILE (데이터베이스이름_Log, 10)

-숫자 10은 용량 !

한줄씩 실행하면 끝 !



+  testdb를 지정한다.(물론 다들 알고 계시겠죠.)
   줄이길 원하는 데이터베이스를 사용하겠다고 지정하는 겁니다.
use testdb

+ 로그파일의 정보를 확인합니다.

dbcc loginfo

+ 현재 지정된 디비가 사용하는 mdf 및 ldf파일의 경로, 이름 및 크기를 확인합니다.

exec sp_helpfile

+ 디비의 로그를 백업해 줍니다.

backup Log testdb to disk='f:\mssql\dbbackup\temp\testdb.bak'

 

+ 로그파일을 최소의 단위로 축소합니다.

backup log testdb with truncate_only


+ 로그파일을 삭제합니다.

backup log testdb with no_log

+ 로그파일을 10메가로 다시 생성합니다.

dbcc shrinkfile (testdb_log, 10)

+ mdf와 ldf파일 확인
exec sp_helpfile


+ 로그파일의 최대크기를 지정(물론 안해도 상관없습니다.)

alter database testdb

    modify file ( name = testdb_log, maxsize = 100 mb )


이상입니다.위에 축소나 삭제에 대한 사항은 원하시는 것을 선택해서 작업하시면 됩니다.

'IT > DB' 카테고리의 다른 글

인덱스 정리  (0) 2009.09.30
인덱스가 있지만 인덱스를 안 타는 경우  (0) 2009.09.30
MS-SQL 실행 계획 확인  (0) 2009.09.30
Inline 쿼리 VS 저장 프로시저  (0) 2009.09.30
SUBQUERY와 INLINE-VIEW의 차이  (1) 2009.09.30