มีประโยชน์ใด ๆ ในการกำหนดฟังก์ชั่นที่นอกเหนือจาก Halloween Protection หรือไม่?


52

เป็นที่ทราบกันดีว่าSCHEMABINDINGฟังก์ชั่นสามารถหลีกเลี่ยงสปูลที่ไม่จำเป็นในแผนการอัพเดทได้:

หากคุณใช้ UDF แบบ T-SQL แบบง่ายที่ไม่ได้แตะตารางใด ๆ (เช่นไม่เข้าถึงข้อมูล) ตรวจสอบให้แน่ใจว่าคุณระบุSCHEMABINDINGตัวเลือกระหว่างการสร้าง UDF สิ่งนี้จะทำให้ UDFs schema-bound และตรวจสอบให้แน่ใจว่าเคียวรีเครื่องมือเพิ่มประสิทธิภาพจะไม่สร้างตัวดำเนินการสปูลที่ไม่จำเป็นสำหรับแผนแบบสอบถามที่เกี่ยวข้องกับ UDF เหล่านี้

มีข้อได้เปรียบอื่น ๆ ของSCHEMABINDINGฟังก์ชั่นแม้ว่าจะไม่สามารถเข้าถึงข้อมูลได้หรือไม่?

คำตอบ:


78

ใช่.

ความล้มเหลวในการระบุWITH SCHEMABINDINGหมายความว่า SQL Server ข้ามการตรวจสอบรายละเอียดตามปกติที่ทำกับเนื้อหาของฟังก์ชัน มันทำเครื่องหมายฟังก์ชั่นเป็นการเข้าถึงข้อมูล (ตามที่กล่าวไว้ในลิงก์ที่ให้ไว้ในคำถาม)

นี่คือการเพิ่มประสิทธิภาพการปฏิบัติงาน ถ้ามันไม่ได้ทำให้สมมติฐานนี้ SQL Server จะต้องดำเนินการตรวจสอบรายละเอียดในทุกการเรียกใช้ฟังก์ชั่น (เนื่องจากฟังก์ชั่น unbound สามารถเปลี่ยนแปลงได้ตลอดเวลา)

มีคุณสมบัติฟังก์ชันที่สำคัญห้าประการ:

  • ชะตา
  • ความแม่นยำ
  • การเข้าถึงข้อมูล
  • การเข้าถึงข้อมูลระบบ
  • การตรวจสอบระบบ

ตัวอย่างเช่นใช้ฟังก์ชัน scalar unbound ต่อไปนี้:

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

เราสามารถดูคุณสมบัติห้าอย่างโดยใช้ฟังก์ชันเมทาดาทา:

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);

ผลลัพธ์

คุณสมบัติการเข้าถึงข้อมูลสองได้รับการตั้งค่าความจริงและอีกสามจะถูกตั้งค่าเป็นเท็จ

สิ่งนี้มีความหมายเกินกว่าที่คาดการณ์ไว้ (ตัวอย่างเช่นใช้ในมุมมองที่จัดทำดัชนีหรือคอลัมน์ที่คำนวณได้ดัชนี)

ผลต่อตัวเพิ่มประสิทธิภาพข้อความค้นหา

determinismคุณสมบัติโดยเฉพาะอย่างยิ่งมีผลต่อการเพิ่มประสิทธิภาพการค้นหา มันมีกฎอย่างละเอียดเกี่ยวกับประเภทของการเขียนซ้ำและการจัดการที่อนุญาตให้ดำเนินการและสิ่งเหล่านี้ถูกจำกัด อย่างมากสำหรับองค์ประกอบที่ไม่ได้กำหนดไว้ ผลข้างเคียงนั้นค่อนข้างบอบบาง

ตัวอย่างเช่นพิจารณาสองตารางต่อไปนี้:

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

... และแบบสอบถามที่ใช้ฟังก์ชัน (ตามที่กำหนดไว้ก่อนหน้านี้):

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

แผนแบบสอบถามเป็นไปตามที่คาดหวังซึ่งมีการค้นหาในตาราง T2:

แสวงหาแผน

อย่างไรก็ตามถ้าเคียวรีแบบโลจิคัลเดียวกันถูกเขียนโดยใช้ตารางที่ได้รับมาหรือนิพจน์ตารางทั่วไป:

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;

แผนการดำเนินการตอนนี้มีการสแกนพร้อมเพรดิเคตที่เกี่ยวข้องกับฟังก์ชันที่ติดอยู่ในตัวกรอง:

สแกนแผน

สิ่งนี้จะเกิดขึ้นหากตารางที่ได้รับหรือนิพจน์ตารางทั่วไปถูกแทนที่ด้วยมุมมองหรือฟังก์ชันในบรรทัด FORCESEEKคำใบ้ (และความพยายามที่คล้ายกันอื่น ๆ ) จะไม่ประสบความสำเร็จ:

ข้อความผิดพลาด

ปัญหาพื้นฐานคือเพิ่มประสิทธิภาพการค้นหาไม่สามารถเรียงลำดับองค์ประกอบแบบสอบถาม nondeterministic เป็นได้อย่างอิสระ

ในการสร้างการค้นหากริยาตัวกรองจะต้องถูกย้ายลงแผนไปที่การเข้าถึงข้อมูล T2 การเคลื่อนไหวนี้จะถูกป้องกันเมื่อฟังก์ชั่นไม่ได้กำหนดไว้

แก้ไขปัญหา

การแก้ไขสำหรับตัวอย่างนี้เกี่ยวข้องกับสองขั้นตอน:

  1. เพิ่ม WITH SCHEMABINDING
  2. ทำให้ฟังก์ชั่นกำหนดขึ้น

ขั้นตอนแรกนั้นไม่สำคัญ ประการที่สองเกี่ยวข้องกับการลบ cast-impl implicit non-deterministic จาก string เป็นdatetime; CONVERTแทนที่ด้วยกำหนด ไม่เป็นที่เพียงพอในตัวเอง

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

คุณสมบัติของฟังก์ชั่นตอนนี้:

คุณสมบัติใหม่

ด้วยการเพิ่มประสิทธิภาพอิสระขึ้นตัวอย่างทั้งหมดในขณะนี้ผลิตที่ต้องการแสวงหาแผน


โปรดทราบว่าใช้CASTไปdatetimeในการทำงานจะไม่ทำงานเพราะมันเป็นไปไม่ได้ที่จะระบุรูปแบบการแปลงในไวยากรณ์ที่:

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

คำจำกัดความของฟังก์ชันนี้สร้างแผนการสแกนและคุณสมบัติแสดงให้เห็นว่ามันยังไม่สามารถกำหนดได้:

คุณสมบัติของฟังก์ชัน CAST

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.