Kinerja Inline-TVF vs Views

9

Saya memiliki database tempat saya menggunakan TVFs sebaris (fungsi nilai tabel) alih-alih tampilan. Sebagai contoh, saya mungkin memiliki dua tabel yang disebut [model mobil] dan [produsen mobil] yang saya gabungkan bersama di dalam TVF [fnCarBrands].

TVF ini kemudian dipanggil oleh TVF lain untuk melakukan pemrosesan dan pelaporan lebih lanjut. Jadi saya mungkin mengambil fungsi saya [fnCarBrands] dan bergabung ke tabel [Tahun Pembelian] untuk membentuk fungsi [fnCarBrandHistory]. Dan seterusnya untuk beberapa lapisan TVF.

Saya mungkin bisa mendapatkan fungsionalitas yang sama menggunakan tampilan, karena TVFs sebaris saya benar-benar hanya gabungan dari tabel dan TVFs lainnya.

Bagaimana kinerja TVFs inline yang ditulis dengan cara ini dibandingkan dengan pandangan?

Tinjuan kemarahan
sumber
Kemungkinan besar Anda akan melihat rencana eksekusi yang sama dan kinerja yang sama.
AK
itulah yang saya pikir, tetapi saya diberitahu bahwa TVF bertindak seperti tanda kurung dalam aljabar - memaksa mesin DB untuk menyelesaikan permintaan itu terlebih dahulu sebelum mengoptimalkan. Menggunakan pandangan, saya diberitahu, memungkinkan pengoptimal untuk mengoptimalkan seluruh permintaan sebagai satu unit.
FistOfFury
Agak seperti catatan tetapi tahu mengapa TVF digunakan sebagai ganti tampilan? Hanya pendekatan kode-monyet vs data-monyet untuk masalah ini?
Mark Storey-Smith
@ MarkStorey-Smith ya, alasannya adalah seperti yang Anda katakan, pendekatan kode-monyet vs data-monyet.
FistOfFury

Jawaban:

12

Pengoptimal kueri memperlakukan fungsi nilai tabel inline persis seperti tampilan:

CREATE FUNCTION dbo.InlineUdf(@arg1 int)
RETURNS TABLE
AS
RETURN 
(
    ... your query here ...
);

Sebuah fungsi meja-nilai multi-pernyataan dijalankan lebih seperti prosedur yang tersimpan. Mereka biasanya harus dieksekusi beberapa kali, daripada dilipat ke dalam kueri utama:

CREATE FUNCTION dbo.MultiStatementUdf (@col1 int)
RETURNS @result TABLE 
(
    id int primary key NOT NULL,
    ... 
)
AS
BEGIN
   DECLARE @var1 int
   set @var1 = 42

   INSERT @result
   SELECT ...
   RETURN
END;
Andomar
sumber
1
@Andomar pemahaman saya adalah TVFs multi-pernyataan dijalankan seperti kotak hitam, mesin tidak tahu apa yang ada di dalamnya dan tidak dapat mengoptimalkan permintaan. Apakah Anda memiliki artikel yang dapat dijadikan referensi yang mengatakan bahwa pandangan dan TVF sebaris setara?
FistOfFury
4

Anda harus membuat tampilan yang mirip dengan fungsi dan meminta setiap melihat pada rencana eksekusi untuk melihat apa yang terjadi dengan masing-masing.

mrdenny
sumber
Persis. Benchmarking, melihat sendiri - ini adalah satu-satunya cara yang dapat diandalkan untuk belajar.
AK
@ Mrdenny Apakah tidak ada cara untuk memprediksi bagaimana pengoptimal akan memperlakukan setiap jenis permintaan? Tentunya ada beberapa aturan yang mengikutinya.
FistOfFury
2
@FistOfFury Ya ada aturan, ribuan demi ribuan, dipuji dengan ratusan tahun kode heuristik pengembang. Itulah sebabnya Anda harus menguji, atau meminta Microsoft untuk kode sumber pengoptimal.
Mark Storey-Smith
Jika Anda lebih ingin memahami bagaimana mesin database menentukan apa yang harus dilakukan, maka Anda perlu membaca tentang SQL Server Internals, amazon.com/s/…
HLGEM
3

Tentu saja membuat tampilan yang memanggil tampilan lain juga merupakan pembunuh kinerja. Jangan menuruni rute itu. Tulis pertanyaan yang Anda butuhkan dan jangan gunakan TVF atau tampilan jika Anda menginginkan kinerja. Ini adalah layering yang menciptakan masalah, ini adalah hampir selalu hal yang buruk untuk dilakukan ketika query database dan Anda dapat dengan cepat berakhir memukul batas jumlah meja Anda dapat referensi juga, terutama karena Anda sering berakhir referensi tabel yang sama di berbagai lapisan. Lebih lanjut, sementara ini sepertinya akan lebih mudah untuk dipertahankan, tidak. Coba debugging atau menambahkan kolom karena persyaratan baru ketika lapisan yang perlu Anda perbaiki ada di bagian bawah.

HLGEM
sumber