Tôi đang cố gắng thiết lập một số dữ liệu để tính toán nhiều trung vị trong SQL Server 2008, nhưng tôi đang gặp sự cố về hiệu suất. Hiện tại, tôi đang sử dụng số điện thoại pattern này ([ví dụ khác bottom). Có, tôi không sử dụng một CTE, nhưng bằng cách sử dụng một sẽ không khắc phục được vấn đề tôi đang có anyways và hiệu suất là người nghèo vì các truy vấn phụ row_number chạy trong nối tiếp, không song song.Nhiều Row_Number() Các cuộc gọi trong một truy vấn SQL đơn
Dưới đây là ví dụ đầy đủ. Bên dưới SQL tôi giải thích vấn đề hơn.
-- build the example table
CREATE TABLE #TestMedian (
StateID INT,
TimeDimID INT,
ConstructionStatusID INT,
PopulationSize BIGINT,
SquareMiles BIGINT
);
INSERT INTO #TestMedian (StateID, TimeDimID, ConstructionStatusID, PopulationSize, SquareMiles)
VALUES (1, 1, 1, 100000, 200000);
INSERT INTO #TestMedian (StateID, TimeDimID, ConstructionStatusID, PopulationSize, SquareMiles)
VALUES (1, 1, 1, 200000, 300000);
INSERT INTO #TestMedian (StateID, TimeDimID, ConstructionStatusID, PopulationSize, SquareMiles)
VALUES (1, 1, 1, 300000, 400000);
INSERT INTO #TestMedian (StateID, TimeDimID, ConstructionStatusID, PopulationSize, SquareMiles)
VALUES (1, 1, 1, 100000, 200000);
INSERT INTO #TestMedian (StateID, TimeDimID, ConstructionStatusID, PopulationSize, SquareMiles)
VALUES (1, 1, 1, 250000, 300000);
INSERT INTO #TestMedian (StateID, TimeDimID, ConstructionStatusID, PopulationSize, SquareMiles)
VALUES (1, 1, 1, 350000, 400000);
--TruNCATE TABLE TestMedian
SELECT
StateID
,TimeDimID
,ConstructionStatusID
,NumberOfRows = COUNT(*) OVER (PARTITION BY StateID, TimeDimID, ConstructionStatusID)
,PopulationSizeRowNum = ROW_NUMBER() OVER (PARTITION BY StateID, TimeDimID, ConstructionStatusID ORDER BY PopulationSize)
,SquareMilesRowNum = ROW_NUMBER() OVER (PARTITION BY StateID, TimeDimID, ConstructionStatusID ORDER BY SquareMiles)
,PopulationSize
,SquareMiles
INTO #MedianData
FROM #TestMedian
SELECT MinRowNum = MIN(PopulationSizeRowNum), MaxRowNum = MAX(PopulationSizeRowNum), StateID, TimeDimID, ConstructionStatusID, MedianPopulationSize= AVG(PopulationSize)
FROM #MedianData T
WHERE PopulationSizeRowNum IN((NumberOfRows + 1)/2, (NumberOfRows + 2)/2)
GROUP BY StateID, TimeDimID, ConstructionStatusID
SELECT MinRowNum = MIN(SquareMilesRowNum), MaxRowNum = MAX(SquareMilesRowNum), StateID, TimeDimID, ConstructionStatusID, MedianSquareMiles= AVG(SquareMiles)
FROM #MedianData T
WHERE SquareMilesRowNum IN((NumberOfRows + 1)/2, (NumberOfRows + 2)/2)
GROUP BY StateID, TimeDimID, ConstructionStatusID
DROP TABLE #MedianData
DROP TABLE #TestMedian
Vấn đề với truy vấn này là SQL Server thực hiện cả hai truy vấn con "ROW__NUMBER() OVER ..." theo thứ tự, không song song. Vì vậy, nếu tôi có 10 trong số các phép tính ROW__NUMBER này, nó sẽ tính toán chúng sau cái kia và tôi nhận được sự tăng trưởng tuyến tính. Tôi có một hệ thống 8-bit 32 GB Tôi đang chạy truy vấn này và tôi sẽ yêu một số tính song song. Tôi đang cố gắng chạy loại truy vấn này trên một bảng hàng 5.000.000.
Tôi có thể nói điều này bằng cách xem xét kế hoạch truy vấn và thấy các sắp xếp trong cùng một đường dẫn thực hiện (hiển thị XML của kế hoạch truy vấn sẽ không hoạt động tốt trên SO).
Vì vậy, câu hỏi của tôi là: Làm thế nào tôi có thể thay đổi truy vấn này để các truy vấn ROW_NUMBER được thực thi song song? Có một kỹ thuật hoàn toàn khác mà tôi có thể sử dụng để chuẩn bị dữ liệu cho nhiều phép tính trung bình không?
+1, đủ mã để thử trên hệ thống của tôi !! –
+1, vì tôi không biết bạn có thể sử dụng các mệnh đề OVER bên ngoài các hàm xếp hạng - trong SQL 2005 cũng vậy, không kém. Woot! –
Philip: Đối với các hàm tổng hợp bình thường, chỉ có mệnh đề PARTITION BY, chứ không phải phần ORDER BY :-( – RBarryYoung