Apakah SQL Sentry Plan Explorer menghitung pembacaan dalam UDF?

9

Saya punya pertanyaan seperti ini:

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

Dalam SQL Sentry Plan Explorer, saya perhatikan saya harus menjalankan Dapatkan Perkiraan Paket di SQL Sentry untuk membuat Rencana Kueri termasuk UDF.

Saat menjalankan 'Dapatkan Rencana Aktual', tidak terlihat bahwa pembacaan logis dan metrik lainnya mencakup operasi yang terjadi di UDF. Dalam kasus seperti ini, apakah satu-satunya solusi untuk menggunakan Profiler?

Gabe
sumber
1
Sepengetahuan saya, mesin kueri itu sendiri tidak memperhitungkan baca di UDF. Ini adalah alasan besar mengapa UDF baik untuk dihindari, mereka buram bagi pengoptimal.
JNK

Jawaban:

11

Penafian yang jelas: Saya bekerja untuk SQL Sentry .

Masalah terbesar yang kita miliki adalah:

  1. Seperti kata @JNK, SQL Server mengaburkan penggunaan UDF, dan tetap melakukan hal-hal buruk dengan mereka (seperti selalu memperkirakan satu baris). Saat Anda membuat paket aktual di SSMS, Anda tidak melihat penggunaannya sama sekali. Kami tunduk pada batasan yang sama karena kami hanya dapat memberikan informasi tentang paket yang disediakan oleh SQL Server kepada kami.
  2. Kami mengandalkan berbagai sumber untuk metrik runtime saat membuat paket yang sebenarnya. Sayangnya paket XML tidak menyertakan pemanggilan fungsi, dan SQL Server tidak mengungkapkan I / O yang dikeluarkan oleh suatu fungsi saat menggunakan SET STATISTICS IO ON;keduanya (ini adalah cara kami mengisi Table I/Otab kami ).

Pertimbangkan tampilan dan fungsi berikut terhadap AdventureWorks2012. Ini hanyalah upaya konyol mengembalikan baris acak dari tabel detail yang diberikan baris acak dari tabel header - kebanyakan untuk memastikan kita menghasilkan I / O sebanyak mungkin, setiap kali.

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

Apa yang Studio Manajemen Lakukan (dan Tidak) Memberitahu Anda

Ambil kueri berikut di SSMS:

SET STATISTICS IO ON;

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

SET STATISTICS IO OFF;

Ketika Anda memperkirakan rencana, Anda mendapatkan rencana untuk permintaan dan satu tunggal rencana untuk fungsi (tidak 5, seperti yang Anda mungkin berharap):

Perkiraan rencana di Studio Manajemen

Anda tidak mendapatkan data I / O sama sekali, jelas, karena permintaan tidak benar-benar dieksekusi. Sekarang, buat rencana yang sebenarnya. Anda mendapatkan 5 baris yang Anda harapkan di kotak hasil, rencana berikut (yang sama sekali tidak membuat penyebutan UDF, kecuali dalam XML Anda dapat menemukannya sebagai bagian dari teks kueri dan sebagai bagian dari Operator Skalar):

Rencana aktual di Studio Manajemen

Dan STATISTICS IOkeluaran berikut (yang sama sekali tidak menyebutkan Sales.SalesOrderDetail, meskipun kita tahu itu harus dibaca dari tabel itu):

Tabel 'SalesOrderHeader'. Pindai hitungan 1, bacaan logis 57, bacaan fisik 0, bacaan baca depan 0, bacaan logis lob 0, bacaan fisik lob 0, bacaan baca lob depan 0.

Apa yang Plan Explorer Memberitahu Anda

Saat kami membuat perkiraan rencana untuk permintaan yang sama, kami tahu tentang hal yang sama dengan SSMS. Namun kami memang menunjukkan hal-hal dengan cara yang sedikit lebih intuitif. Misalnya, perkiraan rencana untuk kueri luar menunjukkan bagaimana output dari fungsi dikombinasikan dengan output dari kueri, dan segera jelas - dalam diagram rencana tunggal - bahwa ada I / O dari kedua tabel :

Perkiraan paket di Plan Explorer

Kami juga menunjukkan rencana fungsi dengan sendirinya , yang saya hanya sertakan untuk kelengkapan:

Perkiraan rencana untuk UDF di Plan Explorer

Sekarang, mari kita lihat rencana yang sebenarnya, yang ribuan kali lebih berguna. Kelemahan di sini adalah, sekali lagi, kami hanya memiliki informasi yang diputuskan untuk ditampilkan oleh SQL Server, jadi kami hanya dapat mengekspos diagram rencana grafis yang diberikan oleh SQL Server kepada kami. Ini bukan situasi di mana kami memutuskan untuk tidak menunjukkan kepada Anda sesuatu yang bermanfaat; kami sebenarnya tidak tahu apa-apa tentang itu berdasarkan pada rencana XML yang disediakan untuk kami. Dalam kasus ini, sama seperti di SSMS, kami hanya melihat rencana kueri luar, dan seolah-olah fungsinya sama sekali tidak dipanggil :

Paket aktual di Plan Explorer

Tab Tabel I / O kami juga masih mengandalkan outputSTATISTICS IO , yang juga mengabaikan aktivitas apa pun yang dilakukan dalam pemanggilan fungsi:

Tabel I / O untuk rencana aktual di Plan Explorer

Namun, kami mendapatkan seluruh tumpukan panggilan untuk Anda. Saya kadang-kadang mendengar orang bertanya, "Pffft, kapan saya akan membutuhkan tumpukan panggilan?" Kami benar-benar dapat memecah waktu yang dihabiskan, CPU yang digunakan, dan jumlah pembacaan (dan, untuk TVF, jumlah baris yang dihasilkan) untuk setiap panggilan fungsi tunggal :

Tumpukan panggilan di Plan Explorer, menampilkan panggilan UDF

Sayangnya kami tidak memiliki kemampuan untuk mengkorelasikan kembali ke tabel mana I / O berasal (lagi, karena SQL Server tidak memberikan informasi itu kepada kami), dan itu tidak dilabeli dengan nama UDF (karena itu ditangkap sebagai pernyataan ad hoc, bukan fungsi panggilan itu sendiri). Tapi apa yang memungkinkan Anda untuk melihat, bahwa Studio Manajemen tidak, adalah apa yang menjadi UDF Anda. Anda masih harus bergabung dengan beberapa titik, tetapi ada lebih sedikit titik dan mereka lebih dekat satu sama lain.

Tentang Profiler

Akhirnya, saya akan sangat menyarankan menjauh dari Profiler, kecuali jika itu untuk mengatur jejak sisi server yang akan Anda jalankan di luar ruang lingkup alat UI. Menggunakan Profiler terhadap sistem produksi hampir pasti akan menyebabkan lebih banyak masalah daripada yang pernah dipecahkannya . Jika Anda ingin mendapatkan informasi ini, silakan gunakan jejak sisi server atau peristiwa yang diperluas, dan pastikan untuk menyaring dengan sangat bijak. Bahkan tanpa profiler, jejak dapat berdampak pada server Anda, dan mengambil showplans melalui acara yang diperpanjang juga bukan hal yang paling efisien di dunia .

Aaron Bertrand
sumber
Ah, saya tidak tahu tentang tumpukan panggilan dalam versi Pro. Itulah tepatnya yang saya cari. Senang mengetahui bahwa itu ada. Pada titik ini, saya tidak berpikir saya bisa membenarkan harga tetapi saya akan tetap mengingatnya untuk situasi masa depan. Apakah ada alasan mengapa SQL Server tidak memberikan informasi I / O untuk UDFs di STATISTIK IO? Itu menyesatkan untuk menghilangkan informasi penting tersebut.
Gabe
3
@ Aku tidak tahu alasannya, maaf. Mungkin membuat konsultasi lebih menguntungkan?
Aaron Bertrand
1
@ gabe sekarang plan explorer benar-benar gratis .. yang disebut penjaga yang memiliki semua fitur edisi pro + ultimate - semuanya gratis.
Kin Shah