10 억 행 테이블에서 "피벗 기반 쿼리"의 실행 시간을 확장하고 개선하는 방법에 대한 조언으로 하루에 백만 명이 늘어납니다.

StackOverflow https://stackoverflow.com/questions/1002086

문제

우리 회사는 텍스트 파일을 구문 분석하기위한 내부 프로젝트를 개발하고 있습니다. 이러한 텍스트 파일은 정기적 인 선전을 사용하여 추출되는 메타 데이터로 구성됩니다. 10 대의 컴퓨터는 24/7 텍스트 파일을 구문 분석하고 추출 된 메타 데이터와 함께 고급 Intel Xeon SQL Server 2005 데이터베이스를 공급합니다.

단순화 된 데이터베이스 스키마는 다음과 같습니다.

항목

| Id | Name   |
|----|--------|
| 1  | Sample |
항목 _attributes

| ItemId | AttributeId |
|--------|-------------|
| 1      | 1           |
| 1      | 2           |
속성

| Id | AttributeTypeId | Value |
|----|-----------------|-------|
| 1  | 1               | 500mB |
| 2  | 2               | 1.0.0 |
속성 유형

| Id | Name    |
|----|---------|
| 1  | Size    |
| 2  | Version |

내부에 다른 메타 데이터가있는 고유 한 텍스트 파일 유형이 많이 있습니다. 모든 텍스트 파일에 대해 Item 그리고 추출 된 모든 메타 데이터 값에 대해 우리는 있습니다 Attribute.

Items_Attributes 중복을 피할 수 있습니다 Attribute x^10을 증가시키기 위해 데이터베이스 크기를 피하는 값.

이 특정 스키마를 사용하면 새로운 정규 표현식을 동적으로 추가하고 어떤 내부 구조에 관계없이 새로운 처리 된 파일에서 새로운 메타 데이터를 얻을 수 있습니다.

또한이를 통해 데이터를 필터링하고 사용자 기준에 따라 동적 보고서를 얻을 수 있습니다. 우리는 필터링하고 있습니다 Attribute 그런 다음 결과 세트를 피벗합니다 (http://msdn.microsoft.com/en-us/library/ms177410.aspx). 이 예제 Pseudo-SQL 쿼리

SELECT FROM Items WHERE Size = @A AND Version = @B

이와 같은 피벗 테이블을 반환합니다

| ItemName | Size  | Version |
|----------|-------|---------|
| Sample   | 500mB | 1.0.0   |

The application has been running for months and performance decreased terribly at the point is no longer usable. Reports should take no more than 2 seconds and Items_Attributes 테이블은 주당 평균 10,000,000 행을 증가시킵니다. 모든 것이 올바르게 색인되어 있으며 쿼리 실행 계획을 분석하고 최적화하는 데 심각한 시간을 보냈습니다.

제 질문은 보고서 실행 시간을 줄이기 위해 어떻게 이것을 확장하겠습니까?

우리는이 가능한 해결책을 가지고 왔습니다.

  • 더 많은 하드웨어를 구매하고 SQL Server 클러스터를 설정하십시오. (적절한 "클러스터링"전략에 대한 조언이 필요합니다)
  • HBase와 같은 키/값 데이터베이스를 사용하십시오 (우리는 문제를 해결할 것인지 실제로 모릅니다).
  • RDBMS 대신 ODBMS를 사용하십시오 (우리는 DB4O를 고려하고 있습니다).
  • 소프트웨어를 클라우드로 옮기십시오 (우리는 경험이 없습니다)
  • 런타임에 보고서를 정적으로 생성합니다. (우리는 정말로 원하지 않습니다)
  • 공통 보고서에 대한 정적 인덱스보기 (성능은 거의 동일합니다)
  • 스키마를 비정상 해제합니다 (일부 보고서 중 일부는 단일 쿼리에 최대 50 개의 테이블이 포함됩니다)
도움이 되었습니까?

해결책

아마도 Entity-Attribute-Value 데이터베이스 모델의 함정에 대한 SQL Server CAT 팀 의이 백서는 다음과 같습니다. http://sqlcat.com/whitepapers/archive/2008/09/03/best-practices-for-emantic-modeling-for-performance.aspx

다른 팁

정확한 테이블 메타 데이터 (인덱싱 세부 사항과 함께), 정확한 쿼리 텍스트 및 실행 계획을 게시하면서 시작했습니다.

현재 테이블 레이아웃을 사용하면 다음과 유사한 쿼리가 있습니다.

SELECT FROM Items WHERE Size = @A AND Version = @B

복합 색인을 사용하면 혜택을 볼 수 없습니다 (Size, Version), 그러한 색인을 구축하는 것은 불가능하기 때문에.

자체 합의가 포함되어 있으므로 색인 뷰도 구축 할 수 없습니다. attributes.

아마도 최선의 결정은 다음과 같이 테이블을 비정상화하는 것입니다.

id  name  size  version

인덱스를 만듭니다 (size, version)

그러한 스키마와 함께 많은 시간을 일했습니다. 그들은 결코 잘 수행하지 않습니다. 가장 좋은 점은 데이터를 필요한대로 저장하는 것입니다.

| ItemName | 크기 | 버전 | | ---------- | ------- | -------- | | 샘플 | 500MB | 1.0.0 |

그러면 당신은 피벗 할 필요가 없습니다. 그리고 BTW, 원래 EAV 스키마를 "정규화"라고 부르지 마십시오. 정규화되지 않았습니다.

OLTP 트랜잭션에 최적화 된 데이터베이스에서 OLAP 쿼리를 발행하는 것을 좋아합니다. 세부 사항을 알지 못하면, 당신이하고있는 쿼리의 종류에 최적화 된 별도의 "datawarehouse"를 구축하는 것이 좋습니다. 여기에는 데이터 집계 (가능한 경우), 탈피 및 1 일 정도의 데이터베이스가 포함됩니다. 당신은 매일 또는 원하는 간격으로 데이터를 점진적으로 업데이트합니다.

정확한 DDL 및 색인을 게시하십시오. ID 열에 인덱스가있는 경우 쿼리가 스캔됩니다.

이런 것 대신

SELECT FROM Items WHERE Size = @A AND Version = @B

당신은 이것을해야합니다

SELECT FROM Items WHERE ID = 1

즉, 텍스트 값을 가져와 색인중인 ID를 찾은 다음 쿼리로 사용하여 결과를 반환해야합니다.

아마도 데이터를 배포하기 위해 분할 기능을 보는 것이 좋습니다.

클러스터링은 성능이 아닌 가용성을 위해 수행됩니다. 하나의 노드가 죽으면 (활성 클러스터), 다른 노드 (수동 클러스터)가 활성화됩니다 ... 물론 활성 활성 클러스터링도 있지만 다른 스토리입니다.

단기 수정은 사용하는 것일 수 있습니다 수평 분할. 나는 당신의 가장 큰 테이블이 있다고 가정합니다 Items_Attributes. 이 테이블을 수평으로 분할하여 각 파티션을 별도의 디스크 컨트롤러에 별도의 파일 그룹에 넣을 수 있습니다.

그것은 당신이 모든 것을보고하려고하지 않는다고 가정합니다. ItemId한 번에 s.

단일 쿼리에 50 개의 테이블을 언급합니다. SQL Server는 단일 모 놀리 식 쿼리에서 최대 256 개의 테이블을 지원하는 반면,이 접근법을 취하면 최적화가 효율적인 계획을 생성 할 가능성이 줄어 듭니다.

스키마에 결혼 한 경우, 보고서 쿼리를 일련의 단계로 나누어 결과를 임시 (#) 테이블로 구체화하는 것을 고려하십시오. 이 접근 방식을 사용하면 쿼리의 가장 선택적인 부분을 분리하여 수행 할 수 있으며, 내 경험상 큰 성능을 제공 할 수 있습니다. 쿼리는 일반적으로 더 관리하기 쉽습니다.

또한 (약간의 긴 샷, 이것) 당신은 당신이 어떤 SQL 서버 버전에 있는지 말하지 않습니다. 그러나 보고서와 관련된 테이블 수와 데이터 양을 고려할 때 SQL 2005에있는 경우 SQL 서버가 SP2 이상으로 패치되어 있는지 확인하는 것이 좋습니다.

수백만 달러의 RowCounts가있는 테이블을 사용하여 ETL 프로젝트에서 작업했는데, SQL 2005 RTM/SP1의 쿼리 최적화기는 테이블 중 하나 이상이있는 곳에 5 개 이상의 테이블을 결합하는 쿼리에 대한 효율적인 계획을 지속적으로 생성 할 수 없다는 것을 발견했습니다. 이 척도의. 이 문제는 SP2에서 해결되었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top