Penafian yang jelas: Saya bekerja untuk SQL Sentry .
Masalah terbesar yang kita miliki adalah:
- 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.
- 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/O
tab 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):
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):
Dan STATISTICS IO
keluaran 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 :
Kami juga menunjukkan rencana fungsi dengan sendirinya , yang saya hanya sertakan untuk kelengkapan:
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 :
Tab Tabel I / O kami juga masih mengandalkan outputSTATISTICS IO
, yang juga mengabaikan aktivitas apa pun yang dilakukan dalam pemanggilan fungsi:
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 :
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 .