Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Fungsi Bernilai Tabel Multi-pernyataan vs Fungsi Bernilai Tabel Sebaris

Dalam meneliti komentar Matt, saya telah merevisi pernyataan asli saya. Dia benar, akan ada perbedaan kinerja antara fungsi bernilai tabel inline (ITVF) dan fungsi bernilai tabel multi-pernyataan (MSTVF) bahkan jika keduanya hanya menjalankan pernyataan SELECT. SQL Server akan memperlakukan ITVF seperti VIEW dalam hal itu akan menghitung rencana eksekusi menggunakan statistik terbaru pada tabel yang bersangkutan. MSTVF setara dengan memasukkan seluruh konten pernyataan SELECT Anda ke dalam variabel tabel dan kemudian bergabung dengannya. Dengan demikian, kompiler tidak dapat menggunakan statistik tabel apa pun pada tabel di MSTVF. Jadi, semua hal dianggap sama, (yang jarang terjadi), ITVF akan berkinerja lebih baik daripada MSTVF. Dalam pengujian saya, perbedaan kinerja dalam waktu penyelesaian dapat diabaikan namun dari sudut pandang statistik, itu terlihat.

Dalam kasus Anda, kedua fungsi tersebut tidak setara secara fungsional. Fungsi MSTV melakukan kueri ekstra setiap kali dipanggil dan, yang terpenting, memfilter id pelanggan. Dalam kueri besar, pengoptimal tidak akan dapat memanfaatkan jenis gabungan lainnya karena perlu memanggil fungsi untuk setiap customerId yang diteruskan. Namun, jika Anda menulis ulang fungsi MSTV Anda seperti ini:

CREATE FUNCTION MyNS.GetLastShipped()
RETURNS @CustomerOrder TABLE
    (
    SaleOrderID    INT         NOT NULL,
    CustomerID      INT         NOT NULL,
    OrderDate       DATETIME    NOT NULL,
    OrderQty        INT         NOT NULL
    )
AS
BEGIN
    INSERT @CustomerOrder
    SELECT a.SalesOrderID, a.CustomerID, a.OrderDate, b.OrderQty
    FROM Sales.SalesOrderHeader a 
        INNER JOIN Sales.SalesOrderHeader b
            ON a.SalesOrderID = b.SalesOrderID
        INNER JOIN Production.Product c 
            ON b.ProductID = c.ProductID
    WHERE a.OrderDate = (
                        Select Max(SH1.OrderDate)
                        FROM Sales.SalesOrderHeader As SH1
                        WHERE SH1.CustomerID = A.CustomerId
                        )
    RETURN
END
GO

Dalam kueri, pengoptimal akan dapat memanggil fungsi itu sekali dan membangun rencana eksekusi yang lebih baik tetapi tetap tidak akan lebih baik daripada ITVS non-parameter yang setara atau VIEW .

ITVF harus lebih disukai daripada MSTVF bila memungkinkan karena tipe data, nullability, dan susunan dari kolom dalam tabel saat Anda mendeklarasikan properti tersebut dalam fungsi bernilai tabel multi-pernyataan dan, yang penting, Anda akan mendapatkan rencana eksekusi yang lebih baik dari ITVF. Dalam pengalaman saya, saya belum menemukan banyak keadaan di mana ITVF adalah pilihan yang lebih baik daripada VIEW tetapi jarak tempuh dapat bervariasi.

Terima kasih kepada Matt.

Penambahan

Karena saya melihat ini muncul baru-baru ini, berikut adalah analisis luar biasa yang dilakukan oleh Wayne Sheffield yang membandingkan perbedaan kinerja antara fungsi Bernilai Tabel Sebaris dan fungsi Multi-Pernyataan.

Postingan blog aslinya.

Salin di SQL Server Central



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menjaga instance koneksi SQL Server tunggal terbuka untuk banyak permintaan di C #?

  2. Database Cadangan SQL Server Express | Cara Menjadwalkan Otomatisasi dan Membersihkan Pencadangan SQL Express

  3. 11 Cara Mengambil Kunci Utama di SQL Server (Contoh T-SQL)

  4. Buat Hubungan di SQL Server 2017

  5. Apakah lebih baik menjalankan banyak perintah sql dengan satu koneksi, atau menyambung kembali setiap saat?