2009-09-07 4 views
1

INT의 4 열 중 최대 70,000 행을 특정 순서로 반환해야하는데 관련된 데이터가 매우 휘발성이어서 최신 상태 여야하기 때문에 매우 얕은 캐싱 만 사용할 수 있습니다. 데이터의 한 가지 속성은 순서대로있을 때 종종 반복적 인 경우가 많다는 것입니다.SQL Server 크로스 행 압축

네트워크 대역폭과 클라이언트 측 처리 시간/리소스를 줄이기 위해 행 수를 줄이는 다양한 방법을 살펴 보았지만 T-SQL에서 기술을 찾을 수는 없었습니다. 반복 행을 단일 행과 '수'열로 압축합니다. 예 : 속으로

prop1 prop2 prop3 prop4 
-------------------------------- 
0  0  1  53 
0  0  2  55 
1  1  1  8 
1  1  1  8 
1  1  1  8 
1  1  1  8 
0  0  2  55 
0  0  2  55 
0  0  1  53 

:

prop1 prop2 prop3 prop4 count 
----------------------------------------- 
0  0  1  53  1 
0  0  2  55  1 
1  1  1  8  4 
0  0  2  55  2 
0  0  1  53  1 

나는이 많은 경우에 가능했던 경우 어떤 70,000 행 결과 세트에서 가장 수천까지 될 것이라고 추정 것입니다.

잘못된 트리를 여기에서 짖고 있습니다 (SQL Server 프로토콜의 일부로 암시 적 압축이 있습니까?).

이렇게하는 방법이 있습니까 (SQL Server 2005)?

왜 이렇게하면 안되나요?

감사합니다.

+0

하나의 핵심 요소 :이 데이터를 쿼리하는 데 사용하는 순서는 무엇입니까? SQL Server는 행이 클러스터형 인덱스 순서로 반환된다는 것을 항상 보장하지는 않으므로이 예제에서 "반복적 인"의미를 결정하는 것은 어렵습니다. –

+0

결과 집합의 일부가 아닌 두 개의 열로 정렬하여 'y'와 'x'를 호출 할 수 있습니다. 건배. –

답변

1

가보기 위하여 고통스러운하지만이 작동합니다 : 올바른 순서를 얻을 수 ROW_NUMBER OVER를 사용하여

  1. 열거 각 행 :

    ;WITH Ordering 
    AS 
    (
        SELECT Prop1,   
        Prop2,   
        Prop3,   
        Prop4, 
        ROW_NUMBER() OVER (ORDER BY Y, X) RN 
        FROM Props 
    ) 
    SELECT 
        CurrentRow.Prop1, 
        CurrentRow.Prop2, 
        CurrentRow.Prop3, 
        CurrentRow.Prop4, 
        CurrentRow.RN - 
        ISNULL((SELECT TOP 1 RN FROM Ordering O3 WHERE RN < CurrentRow.RN AND (CurrentRow.Prop1 <> O3.Prop1 OR CurrentRow.Prop2 <> O3.Prop2 OR CurrentRow.Prop3 <> O3.Prop3 OR CurrentRow.Prop4 <> O3.Prop4) ORDER BY RN DESC), 0) Repetitions 
    FROM Ordering CurrentRow 
    LEFT JOIN Ordering O2 ON CurrentRow.RN + 1 = O2.RN 
    WHERE O2.RN IS NULL OR (CurrentRow.Prop1 <> O2.Prop1 OR CurrentRow.Prop2 <> O2.Prop2 OR CurrentRow.Prop3 <> O2.Prop3 OR CurrentRow.Prop4 <> O2.Prop4) 
    ORDER BY CurrentRow.RN 
    

    요점은 다음과 같다.

  2. 다음 행의 필드가 다른 경우 또는 다음 행이없는 경우에만 결합하여 최대주기를 찾으십시오.
  3. 반복 횟수를 계산하는 것은 현재 행 번호 (이주기의 최대 값으로 추정)를 취하여 이전주기의 최대 행 번호가있는 경우이를 빼는 것입니다.
+0

이렇게하면 여러 행이 반환됩니다. 그들을 걸러 낼 수있는 매우 고가 인'distinct'가 필요할 것입니다. – Eric

+0

이것은 내가 생각했던 것 (창 지식에 대한 지식이 약간 퍼지기는하지만 두려운 것 같습니다)이 시작될 수는 없지만 SQL 2005는 적어도 두 가지를 좋아하는 것 같습니다. OVER의 PARTITION BY 및 ORDER BY 절. 내가 놓친 게 있니? 건배. –

+0

중복을 반환하고 불행히도 COUNT OVER 문이 순서를 지원하지 않기 때문에이 쿼리를 수정하는 중입니다. 나는 더 나은 해결책으로 다시 쓰겠습니다. –

2

count 기능을 사용할 수 있습니다! 이 경우 count 해체 방법 또는 group 자체를 알려주는 group by 절을 사용해야합니다. Gropu by은 SQL의 aggregate function에 사용됩니다.

select 
    prop1, 
    prop2, 
    prop3, 
    prop4, 
    count(*) as count 
from 
    tbl 
group by 
    prop1, 
    prop2, 
    prop3, 
    prop4, 
    y, 
    x 
order by y, x 

업데이트 : 영업 이익은 이러한 yx에 의해 정렬 언급, 결과 세트의 일부. 이 경우 group by의 일부로 yx을 계속 사용할 수 있습니다.

주문에 주문 열이없는 경우 아무런 의미가 없으므로이 경우 에있는 yx을 사용해야합니다.

+0

이것이 효과가있을 수 있지만 질문의 핵심 요소는 "반복적 인"데이터 행을 포함하며이 테이블에 삽입되는 패턴이 무엇인지는 분명하지 않습니다. –

+0

이것은 필요한대로하지 않습니다. 서로 인접하지 않은 행을 그룹으로 묶어 놓고 질문의 일부로 지적했듯이 이것은 매우 중요합니다. 거기에 창을 함수를 함께 사용할 수있는 어떤 방법 있는가? (나는 그들에 대해 거의 안다.) 감사. –

+0

@Kieran : 주문하는 열이없는 한 SQL Server에서는 주문할 필요가 없습니다. 당신은 그 질문에서 당신이하고있는 것을 나타내지 않았습니다. 그러나, 당신은 코멘트에서 한, 그래서 나는 그것을 당신이 그것을 원하는 방식으로 작동 무언가로 변경되었습니다. – Eric

0

네 개의 정수 열이있는 70,000 개의 행은이 쿼리를 동시에 실행하는 워크 스테이션이 많지 않으면 현대 LAN의 대역폭에 대한 실제적인 걱정이 아닙니다. 보다 제한된 대역폭을 가진 WAN에서는 DISTINCT를 사용하여 중복 행을 제거 할 수 있습니다.이 방법은 대역폭을 절약하고 서버 CPU를 약간 소모하는 방식입니다.그러나 피크 부하에서 항상 수행중인 서버가 실제로 오버로드되지 않으면이 추가 소비는 단순한 결과 일뿐입니다. 70,000 개의 행이 아무 것도 없습니다.

+0

대역폭은 확실히 문제가되지 않지만 사용자에게보고하는 행이 70,000 개가 있으면 잃을 수도 있습니다. – Phill