SentryOne Plan Explorer นับการอ่านเป็น UDF หรือไม่


9

ฉันมีคำถามเช่นนี้

select dbo.fn_complexFunction(t.id)
from mytable t

ในSQL Sentry Plan Explorerฉันสังเกตเห็นว่าฉันต้องเรียกใช้ Get Estimated Plan เพื่อให้ Query Plan รวมถึง UDF

เมื่อเรียกใช้ 'รับแผนจริง' จะไม่ปรากฏว่าการอ่านเชิงตรรกะและตัวชี้วัดอื่น ๆ รวมถึงการดำเนินการที่เกิดขึ้นใน UDF ในกรณีเช่นนี้การแก้ปัญหาเพียงอย่างเดียวในการใช้ Profiler คืออะไร


1
สำหรับความรู้ของฉันเครื่องมือค้นหานั้นไม่ได้คำนึงถึงการอ่านเป็น UDF นี่เป็นเหตุผลใหญ่ที่ UDFs ดีที่จะหลีกเลี่ยงพวกมันทึบแสงไปที่เครื่องมือเพิ่มประสิทธิภาพ
JNK

คำตอบ:


11

ปัญหาที่ใหญ่ที่สุดที่เรามีอยู่ที่นี่:

  1. เช่นเดียวกับ @JNK พูดว่า SQL Server ทำให้การใช้ UDF สับสนและทำสิ่งที่เลวร้ายกับพวกเขาต่อไป (เช่นประเมินแถวหนึ่งเสมอ) เมื่อคุณสร้างแผนจริงใน SSMS คุณจะไม่เห็นการใช้งานเลย Plan Explorer ขึ้นอยู่กับข้อ จำกัด เดียวกันเนื่องจากสามารถให้ข้อมูลเกี่ยวกับแผนที่ SQL Server จัดเตรียมไว้ให้เท่านั้น
  2. รหัสอาศัยแหล่งข้อมูลที่แตกต่างกันสำหรับตัวชี้วัดรันไทม์เมื่อสร้างแผนจริง น่าเสียดายที่ XML แผนไม่มีการเรียกใช้ฟังก์ชั่นและ SQL Server จะไม่เปิดเผย I / O ที่เกิดขึ้นจากฟังก์ชั่นเมื่อใช้งานSET STATISTICS IO ON;(นี่คือลักษณะที่Table I/Oแท็บรับข้อมูล)

พิจารณามุมมองและฟังก์ชั่นต่อไปนี้กับ AdventureWorks2012 นี่เป็นเพียงความพยายามโง่ ๆ ในการส่งคืนแถวสุ่มจากตารางรายละเอียดที่กำหนดให้แถวสุ่มจากตารางส่วนหัว - ส่วนใหญ่เพื่อให้แน่ใจว่าเราสร้าง I / O มากที่สุดเท่าที่จะทำได้ทุกครั้ง

CREATE VIEW dbo.myview 
WITH SCHEMABINDING
AS
  SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID() 
    FROM Sales.SalesOrderDetail ORDER BY NEWID();
GO

CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
RETURNS UNIQUEIDENTIFIER
WITH SCHEMABINDING
AS
BEGIN
  RETURN 
  (
    SELECT TOP (1) rowguid FROM dbo.myview 
     WHERE SalesOrderID = @SalesOrderID ORDER BY n
  );
END
GO

สตูดิโอการจัดการแบบใดที่บอกและบอกคุณ

ใช้แบบสอบถามต่อไปนี้ใน SSMS:

SET STATISTICS IO ON;

  SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID) 
    FROM Sales.SalesOrderHeader ORDER BY NEWID();

SET STATISTICS IO OFF;

เมื่อคุณทำประเมินแผนคุณจะได้รับการวางแผนสำหรับการสอบถามและเดียวแผนสำหรับฟังก์ชั่น (5 ไม่ได้ตามที่คุณอาจหวัง):

แผนโดยประมาณใน Management Studio

คุณไม่ได้รับข้อมูล I / O เลยเนื่องจากไม่มีการดำเนินการค้นหา ตอนนี้สร้างแผนจริง คุณจะได้รับ 5 แถวที่คุณคาดไว้ในตารางผลลัพธ์แผนต่อไปนี้ (ซึ่งทำให้ไม่มีการกล่าวถึง UDF ได้อย่างชัดเจนยกเว้นใน XML คุณสามารถค้นหาได้ว่าเป็นส่วนหนึ่งของข้อความค้นหาและเป็นส่วนหนึ่งของ Scalar Operator):

แผนจริงใน Management Studio

และSTATISTICS IOผลลัพธ์ต่อไปนี้(ซึ่งไม่ได้เอ่ยถึงถึงSales.SalesOrderDetailแม้ว่าเรารู้ว่ามันต้องอ่านจากตารางนั้น):

ตาราง 'SalesOrderHeader' จำนวนการสแกน 1, การอ่านเชิงตรรกะ 57, การอ่านทางกายภาพ 0, การอ่านล่วงหน้าอ่าน 0, lob การอ่านตรรกะ 0, lob ทางกายภาพอ่าน 0, lob การอ่านล่วงหน้าอ่าน 0

Plan Explorer บอกอะไรคุณ

เมื่อ PE สร้างแผนโดยประมาณสำหรับการสืบค้นเดียวกันมันจะรู้เกี่ยวกับสิ่งเดียวกันกับ SSMS อย่างไรก็ตามมันแสดงสิ่งต่าง ๆ ในวิธีที่ง่ายกว่าเล็กน้อย ตัวอย่างเช่นแผนโดยประมาณสำหรับเคียวรีด้านนอกแสดงว่าเอาต์พุตของฟังก์ชันรวมกับเอาต์พุตของเคียวรีอย่างไรและชัดเจนทันทีภายในแผนผังแผนเดียวที่มี I / O จากตารางทั้งสอง :

แผนโดยประมาณใน Plan Explorer

นอกจากนี้ยังแสดงแผนของฟังก์ชั่นด้วยตัวเองซึ่งฉันรวมถึงเพื่อความสมบูรณ์เท่านั้น:

แผนโดยประมาณสำหรับ UDF ใน Plan Explorer

ทีนี้มาดูแผนจริงซึ่งมีประโยชน์มากกว่าหลายพันเท่า ข้อเสียที่นี่ก็คือมีข้อมูลที่ SQL Server ตัดสินใจที่จะแสดงเท่านั้นดังนั้นจึงสามารถเปิดเผยไดอะแกรมแผนกราฟิกที่ SQL Server จัดเตรียมไว้ให้เท่านั้น นี่ไม่ใช่สถานการณ์ที่มีคนตัดสินใจไม่ให้แสดงสิ่งที่มีประโยชน์แก่คุณ มันก็ไม่รู้อะไรเกี่ยวกับมันขึ้นอยู่กับ XML แผนที่มีให้ ในกรณีนี้มันเหมือนกับใน SSMS คุณสามารถเห็นแผนของแบบสอบถามภายนอกเท่านั้นและเหมือนกับว่าฟังก์ชันไม่ได้ถูกเรียกใช้เลย :

แผนจริงใน Plan Explorer

แท็บตาราง I / O ก็ยังต้องอาศัยเอาท์พุทของSTATISTICS IOซึ่งยังละเว้นกิจกรรมใด ๆ ที่ดำเนินการในการเรียกใช้ฟังก์ชัน:

ตาราง I / O สำหรับแผนจริงใน Plan Explorer

อย่างไรก็ตาม PE จะรับสายเรียกซ้อนทั้งหมดให้คุณ ฉันเคยได้ยินคนถามเป็นครั้งคราวว่า "Pffft ฉันจะต้องใช้สายเรียกซ้อนเมื่อใด" คุณสามารถแบ่งเวลาที่ใช้ CPU จริงและจำนวนครั้งที่อ่าน (และสำหรับ TVF จำนวนแถวที่ผลิต) สำหรับการเรียกใช้ฟังก์ชันทุกครั้ง :

Call stack ใน Plan Explorer แสดงการโทร UDF

น่าเสียดายที่คุณไม่มีความสามารถในการเชื่อมโยงกลับไปที่ตาราง I / O ใดที่มาจาก (อีกครั้งเนื่องจาก SQL Server ไม่ได้ให้ข้อมูลนั้น) และไม่มีชื่อ UDF (เพราะมันถูกบันทึกเป็นคำสั่งเฉพาะกิจไม่เรียกใช้ฟังก์ชันเอง) แต่สิ่งที่ทำให้คุณเห็นว่า Management Studio ไม่ได้เป็นสิ่งที่ UDF ของคุณเป็นสุนัข คุณยังต้องเข้าร่วมบางจุด แต่มีจุดน้อยลงและอยู่ใกล้กันมากขึ้น

เกี่ยวกับ Profiler

ในที่สุดฉันขอแนะนำอย่างยิ่งให้อยู่ห่างจาก Profiler เว้นแต่จะเป็นการตั้งค่าการติดตามฝั่งเซิร์ฟเวอร์ที่คุณจะใช้สคริปต์จากนั้นเรียกใช้นอกขอบเขตของเครื่องมือ UI ใด ๆ การใช้ Profiler กับระบบการผลิตนั้นเกือบจะแน่นอนว่าจะทำให้เกิดปัญหามากกว่าที่เคยจะแก้ได้ หากคุณต้องการรับข้อมูลนี้โปรดใช้การติดตามฝั่งเซิร์ฟเวอร์หรือเหตุการณ์ที่ขยายเพิ่มและตรวจสอบให้แน่ใจว่าได้กรองอย่างชาญฉลาด แม้จะไม่มี profiler การติดตามสามารถส่งผลกระทบต่อเซิร์ฟเวอร์ของคุณและการดึง showplans จากเหตุการณ์ที่ขยายออกไปก็ไม่ใช่สิ่งที่มีประสิทธิภาพที่สุดในโลกเช่นกัน


อ่าฉันไม่รู้เกี่ยวกับ call stack ในรุ่น Pro นั่นคือสิ่งที่ฉันกำลังมองหา เป็นการดีที่จะรู้ว่ามีอยู่จริง ณ จุดนี้ฉันไม่คิดว่าฉันสามารถปรับราคาได้ แต่ฉันจะคำนึงถึงสถานการณ์ในอนาคต มีเหตุผลใดที่ SQL Server ไม่ให้ข้อมูล I / O สำหรับ UDF ในสถิติ IO? มันทำให้เข้าใจผิดในการละเว้นข้อมูลที่สำคัญดังกล่าว
Gabe

3
@ เกบฉันไม่รู้เหตุผลขอโทษ อาจจะทำให้การให้คำปรึกษามีกำไรมากขึ้น?
Aaron Bertrand

1
@gabe ตอนนี้ plan explorer ไม่มีค่าใช้จ่ายเลย .. มันเรียกว่า sentry one ซึ่งมีคุณสมบัติรุ่น pro + ultimate ทั้งหมดฟรีทั้งหมด
Kin Shah
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.