블로그 이미지
보미아빠

카테고리

보미아빠, 석이 (532)
밥벌이 (16)
싸이클 (1)
일상 (1)
Total
Today
Yesterday

달력

« » 2025.12
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

공지사항

최근에 올라온 글


Aggregation 은 큰 행집합을 하나의 작은 하나의 행집합으로 만드는 것을 말한다. 전형적인 Aggregate 펑션

은 count, min, max, sum avg 가 있다. SQL Server 는 STDEV 이나 VAR 도 지원한다.

나는 이 포스트를 여러개의 포스트로 나누어 쓸것이며, 이번 포스트에서는 "scalar aggregates" 를 다

룬다. Scalar aggregates 는 select list 에서 aggregate 펑션이 사용되고 group by 절이 없는 것을 말한다

Scalar aggregate 는 항상 하나의 단일행을 반환한다.


Scalar Aggregation
Scalar Aggregation 에 대한 하나의 연산자 : Stream aggregate 예제


select count(*) from t
  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1005],0)))
       |--Stream Aggregate(DEFINE:([Expr1005]=Count(*)))
            |--Table Scan(OBJECT:([t]))


이 Aggregation 은 언어에서 처음 학습하는 "Hello World" 와 같은 것이다. stream aggregation든 단지 입

력된 행수를 더하고 그 결과를 반환한다. 이 stream aggregate 는 count([Expr1005]) 를 하는데 bigint 형

으로 계산한다. compute scalar 연산은 int 형태의 output 형태를 만들기 위해 필요하다. 주의할 것은

scalar stream aggregate 연산은 빈 입력셋을 주더라도 하나의 아웃풋을 내는 유일한 연산자 이다. (아마도

유일한 예제이다. 지금 다른것은 생각나지 않는다.)


min max sum 과 같은, 다른 간단한 scalar aggregate funtion 들을 어떻게 쓰는지 쉽게 볼 수 있다. 또한

다중 scalar aggregate 를 한번에 계산 할 수도 있다.

select min(a), max(b) from t
  |--Stream Aggregate(DEFINE:([Expr1004]=MIN([t].[a]), [Expr1005]=MAX([t].[b])))
       |--Table Scan(OBJECT:([t]))

이 계획은 t 라는 테이블을 읽어 a 컬럼의 최소값 b 컬럼의 최대값을 찾는다. 주의깊게 볼 것은 min max

aggregate 들은 결과를 형변환 할 필요가 없다는 것이다. 이러한 aggregate 들은 컬럼 a b 의 기본 type들

에 기초해 계산된다.

avg 와 같은 aggregate들은 실제로는 sum 과 count 로 부터 계산 되어진다.

select avg(a) from t
  |--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [Expr1005]=(0) THEN NULL ELSE

[Expr1006]/CONVERT_IMPLICIT(int,[Expr1005],0) END))
       |--Stream Aggregate(DEFINE:([Expr1005]=COUNT_BIG([t].[a]), [Expr1006]=SUM([t].[a])))
            |--Table Scan(OBJECT:([t]))

위 average 값을 계산하기 위해 sum 과 count 로 부터 계산되어진다. CASE 표현은 0으로 나누지 않기 위해

서 필요하다.


반면 sum 은 이렇게 각각 계산되어질 필요가 없으나, 역시 count 가 필요하다.

select sum(a) from t
  |--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [Expr1005]=(0) THEN NULL ELSE [Expr1006] END))
       |--Stream Aggregate(DEFINE:([Expr1005]=COUNT_BIG([t].[a]), [Expr1006]=SUM([t].[a])))
            |--Table Scan(OBJECT:([t]))

이 CASE 표현은 행이 없을때, 0 대신 null 을 표현하기 위해 필요하다.

 

Scalar Distinct

 

이제는 aggregate 에 DISTINCT 키워드를 추가하면 어떤일이 일어나는지 살펴보자.

select count(distinct a) from t
  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1007],0)))
       |--Stream Aggregate(DEFINE:([Expr1007]=COUNT([t].[a])))
            |--Sort(DISTINCT ORDER BY:([t].[a] ASC))
                 |--Table Scan(OBJECT:([t]))

이 쿼리는 컬럼 a 의 unique 값만의 행수를 계산하는 것이다. sort 연산자를 사용해 컬럼 a 의 중복되는 값을 제외했다.  sort 하면 중복된 값이 서로 인접해 있기 때문에 중복행을 제거하는 쉬운 방법이다.

distinct aggregate 연산들이 모두 중복값 제거가 필요한 것은 아니다. 예를들어, min max 는 distinct 가 있던 없던 상관 없다.

select min(distinct a), max(distinct b) from t
  |--Stream Aggregate(DEFINE:([Expr1004]=MIN([t].[a]), [Expr1005]=MAX([t].[b])))
       |--Table Scan(OBJECT:([t]))

만약, unique 인덱스가 있으면, 중복값 제거절차를 수행하지 않는다. 왜냐하면, unique 인덱스는 중복값이 없다는 것을 보장하기 때문이다.

create unique index ta on t(a)

select count(distinct a) from t

drop index t.ta
  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1007],0)))
       |--Stream Aggregate(DEFINE:([Expr1007]=COUNT([t].[a])))
            |--Index Scan(OBJECT:([t].[ta]))

 

Multiple Distinct


아래 쿼리를 고려해 보자.

select count(distinct a), count(distinct b) from t

위에서 보았듯이 "count(distinct a)"는 컬럼 a 에서 중복값을 제거해 구한다. 유사하게 "count(distinct b)" 컬럼 b 의 중복값을 제거해서 구한다. 그러나, 두 집합이 다르다. 어떻게 동시에 구할수 있을까? 답은 못한다 이다. 첫번째 aggregate 결과를 구하고, 나머지를 구하고, 그런후 두개의 결과를 하나의 결과 row 에 결합한다.

  |--Nested Loops(Inner Join)
       |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1010],0)))
       |    |--Stream Aggregate(DEFINE:([Expr1010]=COUNT([t].[a])))
       |         |--Sort(DISTINCT ORDER BY:([t].[a] ASC))
       |              |--Table Scan(OBJECT:([t]))
       |--Compute Scalar(DEFINE:([Expr1005]=CONVERT_IMPLICIT(int,[Expr1011],0)))
            |--Stream Aggregate(DEFINE:([Expr1011]=COUNT([t].[b])))
                 |--Sort(DISTINCT ORDER BY:([t].[b] ASC))
                      |--Table Scan(OBJECT:([t]))

원래의 쿼리에서 구개의 count 값을 구해 nested loops join 을 수행한다. 입력중 하나는 컬럼 a 의 중복값을 제거하고 나머지는 컬럼 b 의 중복값을 제거한다. 이 nested loop join 은 join 조건이 없다. 이것은 cross join 이다. 왜냐하면 두개의 input rows 는  각각 하나의 결과를 만들고 그것의 cross join 결과 역시 단일 row 이다.

만약 두개이상의 distinct aggregate 연산이 다른 컬럼에 있으면, 하나 이상의 cross join 이 사용된다. 이러한 계획은 non-distinct 와 distinct aggregate 가 같이 섞여 있어도 사용된다. 이럴경우 cross join 의 한쪽에는 sort 가 없다.

다음은 group by 가 포함된 aggregation 이다.

by Craig Freedman

Posted by 보미아빠
, |
EXEC sys.sp_MS_marksystemobject 'sp_who3'
Posted by 보미아빠
, |
7월 21일 엄마는 병원 입니다.
곽생로~ 산부인과 -_- 엄마가 이렇게 많은곳은 처음 입니다. 열라 많아요~


여름이 누나 근심이 가득해요....-_- /
오렌지 주스 한잔 마시면서 ........여름이 기다리는 보미 누나~

드뎌 7월 21일 3시 35분 여름이가 나왔습니다. ^^;; 제가 첫 목욕을 시켜 줬습니다. ^^~~~

보미 누나가 여름이 안고 좋아라 하네요~ 넘 이뻐요 여름이 누님~


모두에게 감사드립니다.
수고한 울 마눌이 젤 감사하구....내가 명품 빽!! 하나 질러줄께........~ ^.^ 좀만 기달료~ 성과급 곧 들어올끼야...ㅋㅋ

우리 4인 가족 열심히 살자구 ~ 화이팅~
보미 아빠
여름이 아빠
은깽이 남편~
Posted by 보미아빠
, |

예전 김평철 CTO님 외 SQL Server 쪽에 한국인이 개입한 적이 없는걸로 안다.
이런분이 많이 나오면 한글로 좀 깊이있게 배울수 있지 않을까.....
하루 4시간은 영어만 쳐다본다. 이게 고마운건지 불행한건지 모르겠다. 자야지.....휴~

코피~ 아흑~

Posted by 보미아빠
, |



Licensing advantages. Server consolidation can also have a significant impact on software
costs by reducing the number of licenses required. With Windows Server 2008 Standard Edition,
three virtual machines can be hosted on one physical server without the need to purchase
additional licenses
. With the Enterprise Edition, an unlimited number of virtual machines can be
hosted on one physical server without the need to purchase additional licenses
. The Enterprise
Edition also provides the ability to reassign licenses in a server farm.

이런말이 있는데......잘 함 봐야 할 듯.....음 windows license 정책을 봐야 할듯
못 찾겠다.......구라친듯..-_-

http://www.microsoft.com/windowsserver2008/en/us/licensing-faq.aspx#virt
Posted by 보미아빠
, |
아래 그림을 많이 보았겠지요?
아래 그림은 Gartner 에서 주로 쓰는 Magic Quardrants 입니다.
유료 자료이고 매우 신뢰성이 높다는 특징이 있습니다.


http://www.gartner.com/technology/research/methodologies/magicQuadrants.jsp

여기서 제목을 찾고 pdf 를 google 신께 굽신 거리면 됩니다. ^^; 어렵게 살면 이렇게 밖에는 쿨럭~
예를 들어 Magic Quadrant for x86 Server Virtualization Infrastructure 를 보고 싶다면 google 에서 찾으면 나오지요


http://www.vmware.com/files/pdf/cloud/Gartner-VMware-Magic-Quadrant.pdf
리포트에서 보면 2010 년까지는 VMware 가 1등 이네요. 타 업체는 저 아래 있군요

 




http://www.citrix.com/site/resources/dynamic/additional/citirix_magic_quadrant_2011.pdf
자료를 보면 Citrix Systems 가 Leaders 그룹에 겨우 찡겼군요....그래서 citirix 가 공짜로 돌립니다.



음 그냥 VMware 로 가야 하는군요......-_- Novell 은 나가 떨어졌나보군요 -_-
Microsoft 는 돈은 있는데 기술력이 후달리지만 리더로 올라는 갔군요. 살아 남을려고 발버둥 치는 모습이 보입니다.

세상은 냉정하니까요~ -_- 평가도 냉정하고... 공부해야지......으쌰 으쌰~

Posted by 보미아빠
, |

CTE

카테고리 없음 / 2011. 7. 18. 03:00
Common Table Expression 

타 데이터베이스의 경우, CTE내용을 쿼리에서 여러번 쓰일경우 실체화 해 한번만 CTE 연산을 하고, 나머지 쿼리에서는 그 결과를 계속 사용해 퀴리를 최적화 하게 된다. 그러나, SQL Server 의 경우 그러한 최적화는 수행하지 못한다. 
(-_- 아~ 꼬질 꼬질 븅신 -_- 들 떨어진...... 드날려보는 2011?은 해결되면 좋으련만 현재 2008 r2 까지는 수행하지 못한다.) 

문론, 재사용을 위해서는 내부적으로 Temp 테이블 등을 이용해 실체화 시켜야 한다. 이러한 DDL 비용이나 Temp를 사용하는 비용이 CTE를 여러번 참조해서 실제로 쿼리하는 비용보다 비쌀 수 도 있다. 하지만 반대의 경우도 있고 다른 DBMS는 지원해준다는 것이 바보 스럽다는 이유이다.  내 생각에 재귀 쿼리를 지원하기 위해 CTE를 만든 것이지 이러한 최적화를 위해서 만든것은 아닌듯 하다.

SQL Server 에서의 CTE는 쿼리를 알아보기 쉽게, 또는 쿼리 자체를 좀 심플하게 적는것 외 도움 되는것이 없다.
 
그러나, predicate merge 기능은 지원한다. CTE 가 테이블 전체를 대상으로 하더라도 외부의 where predicate 가 CTE 내부로 들어가 필터 할 수 있다.  이것도 merge or push predicate 와 마찬가지로 top iterator 등으로 이러한 현상을 막을 수 있다.









Posted by 보미아빠
, |

음 책 검수해야 하는데......
마음 다잡고 다시 으쌰 으쌰~ 

 



if object_id('tblx') is not null
 drop table tblx
 go
 
create table tblx
 (cval char(1)
 ,x int
 ,y int
 )
 go
 
 --필요한 dot design 노가다
 insert tblx values ('1',1,3) , ('1',2,2) , ('1',2,3) , ('1',3,3) , ('1',4,3) , ('1',5,3) , ('1',6,3) , ('1',7,3)
 , ('2',1,2) , ('2',1,3) , ('2',2,1) , ('2',2,4) , ('2',3,4) , ('2',4,2) , ('2',4,3) , ('2',5,1) , ('2',6,1) , ('2',7,1) , ('2',7,2) , ('2',7,3) , ('2',7,4)
 , ('3',1,2) , ('3',1,3) , ('3',2,1) , ('3',2,4) , ('3',3,4) , ('3',4,2) , ('3',4,3) , ('3',5,4) , ('3',6,1) , ('3',6,4) , ('3',7,2) , ('3',7,3)
 , ('4',1,3) , ('4',2,3) , ('4',3,2) , ('4',3,3) , ('4',4,1) , ('4',4,3) , ('4',5,1) , ('4',5,2) , ('4',5,3) , ('4',5,4) , ('4',6,3) , ('4',7,3)
 , ('5',1,1) , ('5',1,2) , ('5',1,3) , ('5',1,4) , ('5',2,1) , ('5',3,1) , ('5',4,1) , ('5',4,2) , ('5',4,3) , ('5',5,4) , ('5',6,4) , ('5',7,1) , ('5',7,2) , ('5',7,3)
 , ('6',1,2) , ('6',1,3) , ('6',2,1) , ('6',2,4) , ('6',3,1) , ('6',4,1) , ('6',4,2) , ('6',4,3) , ('6',5,1) , ('6',5,4) , ('6',6,1) , ('6',6,4) , ('6',7,2) , ('6',7,3)
 , ('7',1,1) , ('7',1,2) , ('7',1,3) , ('7',1,4) , ('7',2,1) , ('7',2,4) , ('7',3,4) , ('7',4,4) , ('7',5,4) , ('7',6,4) , ('7',7,4)
 , ('8',1,2) , ('8',1,3) , ('8',2,1) , ('8',2,4) , ('8',3,1) , ('8',3,4) , ('8',4,2) , ('8',4,3) , ('8',5,1) , ('8',5,4) , ('8',6,1) , ('8',6,4) , ('8',7,2) , ('8',7,3)
 , ('9',1,2) , ('9',1,3) , ('9',2,1) , ('9',2,4) , ('9',3,1) , ('9',3,4) , ('9',4,2) , ('9',4,3) , ('9',4,4) , ('9',5,4) , ('9',6,1) , ('9',6,4) , ('9',7,2) , ('9',7,3)
 , ('0',1,2) , ('0',1,3) , ('0',2,1) , ('0',2,4) , ('0',3,1) , ('0',3,4) , ('0',4,1) , ('0',4,4) , ('0',5,1) , ('0',5,4) , ('0',6,1) , ('0',6,4) , ('0',7,2) , ('0',7,3)
 , ('-',4,1) , ('-',4,2)
 , (':',2,2) , (':',6,2)

 

-- 필요한 컬럼만큼 출력
 select max(case when cval = substring(num,1,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,1,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,1,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,1,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,2,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,2,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,2,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,2,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,3,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,3,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,3,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,3,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,4,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,4,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,4,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,4,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,5,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,5,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,6,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,6,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,6,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,6,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,7,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,7,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,7,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,7,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,8,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,8,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,9,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,9,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,9,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,9,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,10,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,10,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,10,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,10,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,11,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,11,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,12,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,12,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,12,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,12,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,13,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,13,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,13,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,13,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,14,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,14,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,14,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,15,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,15,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,15,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,15,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,16,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,16,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,16,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,16,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,17,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,17,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,17,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,18,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,18,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,18,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,18,1) and y = 4 then '■' else '' end)a
   , max(case when cval = substring(num,19,1) and y = 1 then '■' else '' end)a
   , max(case when cval = substring(num,19,1) and y = 2 then '■' else '' end)a
   , max(case when cval = substring(num,19,1) and y = 3 then '■' else '' end)a
   , max(case when cval = substring(num,19,1) and y = 4 then '■' else '' end)a
   from tblx a
  cross join (select convert(varchar(20), getdate(), 120) num) b -- 도트에 있는 출력할 문자열 입력
  group by x
  order by x


 

Posted by 보미아빠
, |
문제 재현을 질문 하실때, 일일이 설명하기 귀찮을 경우가 많을 것입니다.
windows blog (sankim) 를 보다가 좋은 아티를을 발견 했습니다.

psr.exe 를 이용해 문재 재현을 쉽게 레코딩 및 설명 할 수 있습니다.

첨부파일은 시작>실행 psr.exe 를 통해서 에러를 다시 나게하는 것을 주욱~ capture 한 것입니다.

녹화시작 하고 죽 ~ 녹화 하다가 comment 를 추가 시키고 싶으면 comment 버튼을 누르고 결과를 캡쳐 하시면 됩니다.
슬라이드쇼로도 볼 수 있고 아주 유용한 툴인듯 합니다.
소소한 것은 이걸로 manual 을 만들수도 있을듯 합니다.





Posted by 보미아빠
, |
많은분이 참석 하셨네요. 좋은 시간이 되었을라나 모르겠습니다.




질문은 저분에게 하세요 ^^; 농담이구요 올려주시면 최대한 답변 해보도록 하겠습니다.
앞으로도 스터디 쭈욱 나오실거죠?
역쉬 젊은피가 많이 들어오니 활력이 넘칩니다.

감사합니다.

from a
sqlsql.tistory.com
sqltag.org

P.S
숙봉~ 대단해. 화이팅!
교성이는 역쉬 똑똑해~
성욱아~ 고마워~
마지막으로 책 쓰시는 분들 대단해요 책 나오면 쓴사람들 다 모여서 거사를 치르자구요. 조금만 고생하자!
신입들! 정신 바딱 차리고 열심히 합시다.

Posted by 보미아빠
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함