Có những lợi thế khi sử dụng các bảng tạm thời trên các bảng dẫn xuất trong SQL Server?


8

Tôi đọc các bảng dẫn xuất có hiệu suất tốt hơn các bảng tạm thời, nhưng dù sao nhiều nhà phát triển SQL Server thích các bảng thứ hai. Tại sao? Tôi phải thực hiện các truy vấn với dữ liệu lớn (hàng triệu bản ghi) và tôi muốn chắc chắn rằng tôi đang sử dụng sự lựa chọn tốt nhất.

CREATE TABLE A(
    id BIGINT IDENTITY(1,1) NOT NULL,
    field1 INT NOT NULL,
    field2 VARCHAR(50) NULL,
);

CREATE TABLE B(
    id INT IDENTITY(1,1) NOT NULL,
    field1 VARCHAR(10) NULL,
    field2 INT NULL
);

INSERT INTO A 
    (field1,field2)
VALUES 
    (1,'a'),(2,'b'),(3,'c'),(2,'d'),(5,'e'),
    (6,'f'),(7,'g'),(8,'h'),(9,'i'),(2,'j');

INSERT INTO B 
    (field1,field2)
VALUES 
    ('a',1),('b',2),('c',3),('d',4),('e',5),
    ('f',6),('g',7),('h',8),('i',9),('j',2),('k',3);

DECLARE @begin INT=0,@end INT=200;

Bảng dẫn xuất

/*derived tables*/
SELECT 
    C.id,C.field1,C.field2,C.field3 
FROM
(
    SELECT
        A.id,A.field1,A.field2,B.field2 AS field3, 
        ROW_NUMBER() OVER (ORDER BY A.id) AS iRow
    FROM 
        A INNER JOIN B ON A.field1=B.id
) C
WHERE iRow BETWEEN @begin AND @end;

Bảng tạm thời

/*temporary tables*/
CREATE TABLE #C (
    iRow INT IDENTITY(1,1),
    id bigint,
    field1 INT,
    field2 VARCHAR(50),
    field3 INT );

INSERT INTO #C 
    (id,field1,field2,field3)
SELECT TOP 1000 
    A.id,A.field1,A.field2,B.field2 
FROM  
    A INNER JOIN B ON A.field1=B.id
ORDER BY 
    A.id;

SELECT id,field1,field2,field3 
FROM #C 
WHERE iRow BETWEEN @begin AND @end;

DROP TABLE #C;

1
Bạn có SELECT TOP 1000mà không có ORDER BY, đó là không tốt. Tôi nghĩ bạn cần thêm ORDER BY A.id;hai cách để tương đương.
ypercubeᵀᴹ

Nó chỉ là một mẫu. Mục tiêu là để hiển thị chủ đề chính của câu hỏi của tôi.
norgematos

Câu trả lời:


6

@ user16484 đã hướng bạn đến cái nào có hiệu suất tốt hơn: Bảng có nguồn gốc hoặc Bảng tạm thời trong nhận xét.

Đồng thời xem Bảng tạm thời 'so với' Biến bảng 'so với' CTE. trong đó cũng bao gồm các bảng dẫn xuất.

Tóm tắt nhanh: #temp bảng có thể được lập chỉ mục, có thể có chỉ mục / ràng buộc UNIITE, có thể được tham chiếu nhiều lần trong cùng một truy vấn, có thể được tham chiếu (TỪ hoặc THAM GIA) bằng nhiều truy vấn. Các bảng đã tạo có thể được tham chiếu (TỪ hoặc THAM GIA) một lần trong một truy vấn.

Hiệu suất khôn ngoan, rút ​​Profiler cho SQL: BatchCompleted và RPC: Đã hoàn thành, xem các cột Đọc, Viết, CPU và Thời lượng và xem một vài lần chạy bảng dẫn xuất so với bảng #temp so với bảng #temp được lập chỉ mục mỗi truy vấn cụ thể.

Nói chung - nếu bạn sẽ sử dụng nó nhiều lần, bảng #temp sẽ thắng. Nếu bạn tham gia nhiều bảng, bảng #temp có thể thắng. Nếu bạn chỉ tham gia một vài bảng, bảng dẫn xuất có cơ hội chiến thắng hợp lý. Điểm chuẩn đó!


6

Nói chung, nó phụ thuộc vào các truy vấn cụ thể của bạn và kích thước của các kết quả tạm thời.

Đối với kịch bản cụ thể được đưa ra, đó là phân trang, các bảng tạm thời là hoàn toàn không cần thiết. Tại sao bạn chỉ muốn lưu 1000 hàng vào bảng tạm thời để sau đó trả về 200 đầu tiên? Sử dụng bảng 'dẫn xuất' hoặc CTE trong kịch bản này sẽ hiệu quả hơn nhiều, vì tập hợp kết quả đầy đủ không phải được lưu trữ ở bất cứ đâu hoặc trong hầu hết các trường hợp thậm chí được tạo ra. Ví dụ: khi yêu cầu trang 1 gồm 200 hàng, chỉ 200 hàng đầu tiên sẽ phải được truy xuất từ ​​các bảng cơ sở (giả sử các chỉ mục hiện có có thể hỗ trợ thứ tự sắp xếp được yêu cầu trong truy vấn).


1
+1, mặc dù tôi sẽ thêm rằng việc sử dụng các bảng dẫn xuất cũng cho phép Trình tối ưu hóa truy vấn xử lý cả hai truy vấn cùng một lúc. Điều này có thể tốt hoặc đôi khi xấu, một lần nữa "tùy thuộc vào truy vấn cụ thể". Đó là lý do tại sao luôn luôn tốt khi kiểm tra cả hai (trên dữ liệu thực chứ không phải dữ liệu mẫu) thay vì đoán :-).
Solomon Rutzky 17/03/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.