Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Bảng nào có hiệu suất cao hơn, CTE hay bảng tạm thời?

Nó phụ thuộc.

Trước hết

Biểu thức bảng chung là gì?

CTE (không đệ quy) được xử lý rất giống với các cấu trúc khác cũng có thể được sử dụng làm biểu thức bảng nội tuyến trong SQL Server. Bảng gốc, Chế độ xem và các hàm có giá trị bảng nội tuyến. Lưu ý rằng trong khi BOL nói rằng CTE "có thể được coi là tập kết quả tạm thời" thì đây là một mô tả hoàn toàn logic. Thường xuyên hơn là nó không được chuyển hóa thành nguyên liệu theo đúng nghĩa của nó.

Bảng tạm thời là gì?

Đây là tập hợp các hàng được lưu trữ trên các trang dữ liệu trong tempdb. Các trang dữ liệu có thể nằm một phần hoặc toàn bộ trong bộ nhớ. Ngoài ra, bảng tạm thời có thể được lập chỉ mục và có thống kê cột.

Dữ liệu thử nghiệm

CREATE TABLE T(A INT IDENTITY PRIMARY KEY, B INT , F CHAR(8000) NULL);

INSERT INTO T(B)
SELECT TOP (1000000)  0 + CAST(NEWID() AS BINARY(4))
FROM master..spt_values v1,
     master..spt_values v2;

Ví dụ 1

WITH CTE1 AS
(
SELECT A,
       ABS(B) AS Abs_B,
       F
FROM T
)
SELECT *
FROM CTE1
WHERE A = 780

Lưu ý trong kế hoạch trên không có đề cập đến CTE1. Nó chỉ truy cập trực tiếp vào các bảng cơ sở và được xử lý giống như

SELECT A,
       ABS(B) AS Abs_B,
       F
FROM   T
WHERE  A = 780 

Viết lại bằng cách cụ thể hóa CTE thành một bảng tạm thời trung gian ở đây sẽ phản tác dụng rất lớn.

Hiện thực hóa định nghĩa CTE của

SELECT A,
       ABS(B) AS Abs_B,
       F
FROM T

Sẽ liên quan đến việc sao chép khoảng 8GB dữ liệu vào một bảng tạm thời, sau đó vẫn phải chọn từ nó.

Ví dụ 2

WITH CTE2
     AS (SELECT *,
                ROW_NUMBER() OVER (ORDER BY A) AS RN
         FROM   T
         WHERE  B % 100000 = 0)
SELECT *
FROM   CTE2 T1
       CROSS APPLY (SELECT TOP (1) *
                    FROM   CTE2 T2
                    WHERE  T2.A > T1.A
                    ORDER  BY T2.A) CA 

Ví dụ trên mất khoảng 4 phút trên máy của tôi.

Chỉ có 15 hàng trong số 1.000.000 giá trị được tạo ngẫu nhiên khớp với vị từ nhưng quá trình quét bảng tốn kém diễn ra 16 lần để xác định các giá trị này.

Đây sẽ là một ứng cử viên tốt để hiện thực hóa kết quả trung gian. Việc viết lại bảng tạm thời tương đương mất 25 giây.

INSERT INTO #T
SELECT *,
       ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM   T
WHERE  B % 100000 = 0

SELECT *
FROM   #T T1
       CROSS APPLY (SELECT TOP (1) *
                    FROM   #T T2
                    WHERE  T2.A > T1.A
                    ORDER  BY T2.A) CA 

Việc vật liệu hóa trung gian một phần của truy vấn thành một bảng tạm thời đôi khi có thể hữu ích ngay cả khi nó chỉ được đánh giá một lần - khi nó cho phép phần còn lại của truy vấn được biên dịch lại tận dụng các thống kê về kết quả được thực hiện hóa. Một ví dụ về cách tiếp cận này là trong bài viết SQL Cat Khi nào cần chia nhỏ các truy vấn phức tạp.

Trong một số trường hợp, SQL Server sẽ sử dụng bộ đệm để lưu vào bộ đệm một kết quả trung gian, ví dụ:của một CTE và tránh phải đánh giá lại cây con đó. Điều này được thảo luận trong mục Kết nối (đã di chuyển) Cung cấp gợi ý để buộc thực hiện hóa trung gian các CTE hoặc bảng dẫn xuất. Tuy nhiên, không có số liệu thống kê nào được tạo về điều này và ngay cả khi số lượng hàng được phân phối khác nhau rất nhiều so với ước tính thì kế hoạch thực thi đang tiến hành cũng không thể tự động điều chỉnh để đáp ứng (ít nhất là trong các phiên bản hiện tại. Kế hoạch truy vấn thích ứng có thể trở nên khả thi trong tương lai).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. làm thế nào để bỏ qua một hàng xấu trong nguồn tệp phẳng ssis

  2. Hàm IndexOf trong T-SQL

  3. CTE vòng lặp vô hạn với TÙY CHỌN (maxrecursion 0)

  4. Cách xác định giá trị của bạn dưới dạng DBA cho người điều hành tài chính

  5. Cách kết nối với cơ sở dữ liệu máy chủ SQL từ ứng dụng Windows 10 UWP