2017-04-15 12 views
2

Azure 데이터웨어 하우스에서 JOIN 할 계획이고 잠재적으로 집계하려는 필드에 분산 테이블에 HASH를 사용하는 것이 좋습니다. 또한 사용할 필드에 대한 통계를 작성하는 것이 좋습니다.통계는 Azure Data Warehouse에서 해싱과 같은 JOINS 필드를 지원합니까?

같은 양의 레코드와 필드가있는 두 개의 테이블이 있다고 가정 해 보겠습니다. 한 테이블은 매우 고유 한 키에서 해시되며, 다른 테이블은 ROUND_ROBIN이며 여기에서 데이터는 60 개의 데이터베이스에서 균등하게 무작위로 나뉩니다.

-- CustomerID is alphanumeric 
SELECT 
    [ProductID] 
    ,COUNT(DISTINCT [CustomerID]) AS [Unique Records] 
FROM [dbo].[FactTable] 
GROUP BY 
    [Product] 

해시 된 테이블에서 해시 된 키를 집계하면 0.05 초 이내에 결과가 반환되는 것을 확인할 수 있습니다. 동일한 집계를 사용하는 라운드 로빈 테이블에서 0.51 초입니다.

CREATE STATISTICS [ProductID] ON [dbo].[FactTable] ([ProductID]); 
CREATE STATISTICS [CustomerID] ON [dbo].[FactTable] ([CustomerID]); 

집계중인 필드에 통계를 적용해도 해시 된 테이블은 여전히 ​​0.05 초 내에 반환됩니다. 변경 없음. 라운드 로빈 테이블에 동일한 작업을 수행하면 해시 값과 동일한 결과가 0.05 초 이내에 반환됩니다.

참고 : 초대형 자원 (최대 메모리 할당) 2000 DWU 실행 쿼리

해시 키의 분포를 조사, 내가 140,000,000 레코드가 60 데이터베이스 중 하나 개 유통에 저장됩니다 발견했다. 5 천만 개의 다른 레코드가 다른 59 개의 데이터베이스에 균등하게 분산되어 있습니다. 기본값은 내 해시 키를 해시 후보로 사용하지 않는 것입니다.

제 질문은 통계가있는 라운드 로빈 테이블이 동일한 테이블에서 성능이 뛰어나지 만 다른 테이블과 해시하고 있습니다. 해당 키를 사용하여 JOINS에서 라운드 로빈을 사용하면 동일한 성능이 유지됩니까? 아직 완전히 테스트하지는 않았지만 최선의 방법을 찾고 있습니다.

통계가 조인에 도움이됩니까? 필자가 읽은 기사 중 일부는 배포 키에 대해 라운드 로빈을 고려할 때 다른 사람이 접근 방식에 대해보다 확실한 답을 얻었는지 확인하는 것으로 나타났습니다. 위의 예에서와 같이 1 억 4 천만 명의 데이터 스큐가 발생하지 않는 후보자는 없습니다. 모든

+1

응답을 자세히 나타내려면 테스트 한 모든 쿼리에 대한 Explain 계획을 게시하면 도움이됩니다. 쿼리 앞에 'EXPLAIN'이라는 단어를 넣고 실행 한 다음 XML을 질문에 복사하십시오. – GregGalloway

+0

실제로는 없지만 참조 용으로 SQL 샘플이 포함되어 있습니다. 그것은 단지 SELECT COUNT (DISTINCT) GROUP BY 쿼리입니다. – Fastidious

+0

하나 얻을 수 있습니까? 통계가 설명 계획을 변경하는지 또는 성능 차이가 캐싱과 관련이 있는지 확인하고 싶습니다. – GregGalloway

답변

1

첫째, 푸른 SQL 데이터웨어 하우스의 현재 버전에서는, 당신은 항상GROUP BY을 당신이 사용하게 될 컬럼에 대한 통계를 조인 만들 그들이 관련이없는 당신이 통계를하지 않고있어 타이밍을 무시한다.

좋은 해시 키에 대한 기준 중 하나는 distributes the data evenly입니다. 당신이 좋은 후보자가없는 경우에, ROUND_ROBIN는 선택권이다. ROUND_ROBIN에 대해 염두에 두어야 할 점은 항상 데이터 이동을 가져 오지만 때로는 문제가되지 않는다는 것입니다. 핵심 쿼리가 무엇인지에 따라 달라집니다. 내 조언은 그들을 위해 최적화하는 것입니다.

예제를 들어 보면 성능이 너무 빨라 너무 많은 시간을 소비 할 가치가 없습니다. 더 현실적인 쿼리가 있습니까?

Azure SQL 데이터웨어 하우스는 here과 같이 SQL Server와 비슷한 캐시를 수행합니다.

포털에서웨어 하우스를 구축 할 때 사용할 수있는 AdventureWorksDW 샘플을 사용하여 테스트 장비를 조롱했습니다. 이러한 샘플 쿼리에 대해 해시 테이블의 성능이 크게 향상되었지만 (YMMV) 차이가있을 수 있습니다. 6 억 행의 테이블

-- 603,980,000 rows 
CREATE TABLE dbo.FactTable_rr 
WITH ( 
    DISTRIBUTION = ROUND_ROBIN, 
    CLUSTERED COLUMNSTORE INDEX 
) 
AS 
SELECT a.ProductKey AS [ProductID], a.CustomerKey AS [CustomerID] 
FROM [dbo].[FactInternetSales] a 
    CROSS JOIN (SELECT TOP 1000 1 FROM [dbo].[FactInternetSales]) b(c) 
    CROSS JOIN (SELECT TOP 10 1 FROM [dbo].[FactInternetSales]) c(c) 
GO 


CREATE STATISTICS st_dbo_FactTable_rr_ProductID ON dbo.FactTable_rr (ProductID) WITH FULLSCAN; 
CREATE STATISTICS st_dbo_FactTable_rr_CustomerID ON dbo.FactTable_rr (CustomerID) WITH FULLSCAN; 
GO 


CREATE TABLE dbo.FactTable_hh 
WITH ( 
    DISTRIBUTION = HASH([ProductID]), 
    CLUSTERED COLUMNSTORE INDEX 
) 
AS 
SELECT * 
FROM FactTable_rr 
GO 

CREATE STATISTICS st_dbo_FactTable_hh_ProductID ON dbo.FactTable_hh (ProductID) WITH FULLSCAN; 
CREATE STATISTICS st_dbo_FactTable_hh_CustomerID ON dbo.FactTable_hh (CustomerID) WITH FULLSCAN; 
GO 



-- Find data skew for a distributed table 
DBCC PDW_SHOWSPACEUSED('dbo.FactTable_rr'); 
DBCC PDW_SHOWSPACEUSED('dbo.FactTable_hh'); 
GO 


--EXPLAIN 
SELECT 
    [ProductID], 
    COUNT(DISTINCT [CustomerID]) AS [Unique Records] 
FROM [dbo].[FactTable_rr] 
GROUP BY [ProductID] 
OPTION (LABEL = 'rr'); 


--EXPLAIN 
SELECT 
    [ProductID], 
    COUNT(DISTINCT [CustomerID]) AS [Unique Records] 
FROM [dbo].[FactTable_hh] 
GROUP BY [ProductID] 
OPTION (LABEL = 'hh'); 


-- Summary 
SELECT [label], COUNT(*) records, CAST(AVG(total_elapsed_time)/1000. AS DECIMAL(10,2)) total_elapsed_time_s 
FROM sys.dm_pdw_exec_requests 
WHERE [label] IS NOT NULL 
    AND command Like 'select%' 
GROUP BY [label]; 

내 결과 :

My results

나는 두 개의 쿼리 (rr, 0의 계획을 설명을 보면) 데이터 이동이없는 해시 테이블에 대한 훨씬 간단한 계획이 있습니다. 'rr'플랜에는 SHUFFLE_MOVE 연산자가 들어 있으며 분산 테이블을 재 분산합니다.

+0

제 문제는 단순한 쿼리 일지라도 10 억 개의 행에 매달려 있다는 것입니다. 매우 고유 한 행에서 COUNT (DISTINCT)를 수행하지 않으려 고 고도로 고유 한 행에서 DATEPART 및 GROUP BY를 그룹화하는 간단한 쿼리는 시간이 오래 걸립니다. – Fastidious

+0

성능에 대해 설명한 것과 완전히 다른 시나리오처럼 들립니다. DDL, 실행중인 샘플 데이터 및 실제 쿼리 및 Explain 계획을 제공 할 수 있다면 누군가가 당신을 도울 수 있습니다. 솔직히 말해서 방금 설명한 시나리오는 별개의 질문처럼 들린다. – wBob

+0

기본적으로 동일한 쿼리이지만 레코드가 더 많은 다른 테이블에 있습니다. 유일한 차이점은 해당 필터에 10 억 개의 레코드가있는 데이터 세트를 기반으로하는 필터가 하나 더 있다는 것입니다. 여기에서 보여주는 예제 쿼리는 다른 테이블로 분할 된 2 억 개의 레코드 만있는 데이터의 다른 하위 세트를 기반으로합니다. . 나눠서 쿼리를 몇 초 내에 반환 할 수있었습니다. 그러나 그렇습니다, 그것은 다른 질문 일 수 있습니다. 더 큰 데이터에서 동일한 쿼리를 사용할 수없는 이유는 무엇입니까? :) – Fastidious