Có bất kỳ lợi ích nào để HỌC BỔNG một chức năng ngoài Bảo vệ Halloween không?


52

Điều nổi tiếng là SCHEMABINDINGmột hàm có thể tránh được một bộ đệm không cần thiết trong các kế hoạch cập nhật:

Nếu bạn đang sử dụng các UDF T-SQL đơn giản không chạm vào bất kỳ bảng nào (tức là không truy cập dữ liệu), hãy đảm bảo bạn chỉ định SCHEMABINDINGtùy chọn trong khi tạo UDF. Điều này sẽ làm cho các lược đồ UDF bị ràng buộc và đảm bảo rằng trình tối ưu hóa truy vấn không tạo ra bất kỳ toán tử bộ đệm không cần thiết nào cho các kế hoạch truy vấn liên quan đến các UDF này.

Có bất kỳ lợi thế nào khác của SCHEMABINDINGchức năng, ngay cả khi nó không truy cập dữ liệu?

Câu trả lời:


78

Đúng.

Không chỉ định WITH SCHEMABINDINGcó nghĩa là SQL Server bỏ qua các kiểm tra chi tiết mà nó thường thực hiện trên thân hàm. Nó chỉ đơn giản đánh dấu chức năng là truy cập dữ liệu (như được đề cập trong liên kết được đưa ra trong câu hỏi).

Đây là một tối ưu hóa hiệu suất. Nếu nó không đưa ra giả định này, SQL Server sẽ phải thực hiện kiểm tra chi tiết cho mọi lời gọi hàm (vì hàm không liên kết có thể thay đổi bất cứ lúc nào).

năm thuộc tính chức năng quan trọng:

  • Chủ nghĩa quyết đoán
  • Độ chính xác
  • Truy cập dữ liệu
  • Truy cập dữ liệu hệ thống
  • Xác minh hệ thống

Ví dụ: lấy hàm vô hướng sau:

CREATE FUNCTION dbo.F
(
    @i integer
)
RETURNS datetime
AS
BEGIN
    RETURN '19000101';
END;

Chúng ta có thể xem xét năm thuộc tính bằng hàm siêu dữ liệu:

SELECT 
    IsDeterministic = OBJECTPROPERTYEX(Func.ID, 'IsDeterministic'),
    IsPrecise = OBJECTPROPERTYEX(Func.ID, 'IsPrecise'),
    IsSystemVerified = OBJECTPROPERTYEX(Func.ID, 'IsSystemVerified'),
    UserDataAccess = OBJECTPROPERTYEX(Func.ID, 'UserDataAccess'),
    SystemDataAccess = OBJECTPROPERTYEX(Func.ID, 'SystemDataAccess')
FROM (VALUES(OBJECT_ID(N'dbo.F', N'FN'))) AS Func (ID);

Kết quả

Hai thuộc tính truy cập dữ liệu đã được đặt thành đúng và ba thuộc tính khác được đặt thành sai .

Điều này có ý nghĩa vượt ra ngoài những điều có thể được mong đợi (ví dụ, sử dụng trong các chế độ xem được lập chỉ mục hoặc các cột được tính toán được lập chỉ mục).

Hiệu ứng trên trình tối ưu hóa truy vấn

Các định mệnh bất động sản nói riêng ảnh hưởng đến truy vấn tối ưu. Nó có các quy tắc chi tiết liên quan đến các loại viết lại và thao tác mà nó được phép thực hiện, và những điều này bị hạn chế rất nhiều cho các yếu tố không xác định. Các tác dụng phụ có thể khá tinh tế.

Ví dụ, hãy xem xét hai bảng sau:

CREATE TABLE dbo.T1
(
    SomeInteger integer PRIMARY KEY
);
GO
CREATE TABLE dbo.T2
(
    SomeDate datetime PRIMARY KEY
);

... và một truy vấn sử dụng hàm (như được xác định trước đó):

SELECT * 
FROM dbo.T1 AS T1
JOIN dbo.T2 AS T2
    ON T2.SomeDate = dbo.F(T1.SomeInteger);

Kế hoạch truy vấn như mong đợi, bao gồm tìm kiếm vào bảng T2:

Tìm kiếm kế hoạch

Tuy nhiên, nếu cùng một truy vấn logic được viết bằng bảng dẫn xuất hoặc biểu thức bảng chung:

WITH CTE AS
(
    SELECT *, dt = dbo.F(T1.SomeInteger) 
    FROM dbo.T1 AS T1
)
SELECT * 
FROM CTE
JOIN dbo.T2 AS T2
    ON T2.SomeDate = CTE.dt;

-- Derived table
SELECT
    *
FROM 
(
    SELECT *, dt = dbo.F(T1.SomeInteger)
    FROM dbo.T1 AS T1
) AS T1
JOIN dbo.T2 AS T2
    ON T2.SomeDate = T1.dt;

Kế hoạch thực hiện hiện có tính năng quét, với vị từ liên quan đến chức năng bị mắc kẹt trong Bộ lọc:

Kế hoạch quét

Điều này cũng xảy ra nếu bảng dẫn xuất hoặc biểu thức bảng chung được thay thế bằng hàm xem hoặc hàm trong dòng. Một FORCESEEKgợi ý (và các nỗ lực tương tự khác) sẽ không thành công:

Thông báo lỗi

Vấn đề cơ bản là trình tối ưu hóa truy vấn không thể sắp xếp lại các yếu tố truy vấn không xác định là tự do .

Để thực hiện tìm kiếm, vị từ Bộ lọc sẽ cần được chuyển xuống kế hoạch để truy cập dữ liệu T2. Chuyển động này được ngăn chặn khi chức năng không xác định.

Sửa chữa

Khắc phục cho ví dụ này bao gồm hai bước:

  1. Thêm vào WITH SCHEMABINDING
  2. Làm cho hàm xác định

Bước đầu tiên là tầm thường. Thứ hai liên quan đến việc loại bỏ các hàm ẩn không xác định từ chuỗi sang datetime; thay thế nó bằng một quyết định CONVERT. Bản thân nó cũng không đủ .

ALTER FUNCTION dbo.F
(
    @i integer
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
    -- Convert with a deterministic style
    RETURN CONVERT(datetime, '19000101', 112);
END;

Các thuộc tính chức năng là:

Tài sản mới

Với trình tối ưu hóa được giải phóng, tất cả các ví dụ hiện tạo ra kế hoạch tìm kiếm mong muốn .


Lưu ý rằng việc sử dụng một CASTđể datetimetrong chức năng sẽ không hoạt động, bởi vì nó không thể xác định một phong cách chuyển đổi trong cú pháp rằng:

ALTER FUNCTION dbo.F
(
    @i integer
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
    -- Convert with a deterministic style
    RETURN CAST('19000101' AS datetime);
END;

Định nghĩa hàm này tạo ra kế hoạch quét và các thuộc tính cho thấy nó vẫn không xác định:

Thuộc tính hàm CAST

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.