Masukkan perbedaan kinerja antara tabel sementara dan variabel tabel

12

Saya memiliki masalah berikut dalam SQL Server 2005: mencoba memasukkan beberapa baris ke dalam variabel tabel membutuhkan banyak waktu dibandingkan dengan insert yang sama menggunakan tabel sementara.

Ini adalah kode yang akan dimasukkan ke dalam variabel tabel

DECLARE @Data TABLE(...)
INSERT INTO @DATA( ... )
SELECT ..
FROM ...

Ini adalah kode untuk dimasukkan ke tabel temp

CREATE #Data TABLE(...)
INSERT INTO #DATA( ... )
SELECT ..
FROM ...
DROP TABLE #Data

Tabel sementara tidak memiliki kunci atau indeks, bagian yang dipilih adalah sama antara 2 kueri, dan jumlah hasil yang dikembalikan oleh pilih adalah ~ 10.000 baris. Waktu yang diperlukan untuk menjalankan pemilihan saja ~ 10 detik.

Versi temp table membutuhkan waktu hingga 10 detik untuk dieksekusi, saya harus menghentikan versi variabel tabel setelah 5 menit.

Saya harus menggunakan variabel tabel karena kueri adalah bagian dari fungsi nilai tabel, yang tidak memungkinkan akses ke tabel sementara.

Paket eksekusi untuk versi variabel tabel Rencana eksekusi

Rencana eksekusi untuk versi tabel temp Rencana eksekusi

Munissor
sumber

Jawaban:

8

Perbedaan yang jelas antara kedua rencana adalah bahwa yang cepat paralel dan yang lambat satu seri.

Ini adalah salah satu keterbatasan dari rencana yang dimasukkan ke dalam variabel tabel. Seperti yang disebutkan dalam komentar (dan tampaknya memiliki efek yang diinginkan), Anda dapat mencoba melakukannya

INSERT INTO @DATA ( ... ) 
EXEC('SELECT .. FROM ...')

untuk melihat apakah itu mengatasi batasan.

Martin Smith
sumber
Itu adalah saran yang bagus, meskipun saya EXECpikir Anda tidak dapat menggunakan fungsi .... kira saya salah
Lamak
1
@Lamak - Doh! Anda tidak bisa jadi ini tidak akan berfungsi untuk OP. Invalid use of a side-effecting operator 'INSERT EXEC' within a function.. The OPENQUERYbekerja di sekitar kekuatan kerja sekalipun.
Martin Smith
Ah, senang tahu, terima kasih atas klarifikasi
Lamak
2
Sebagai aturan umum, Anda tidak ingin menggunakan variabel tabel jika Anda akan mengharapkan untuk mendapatkan aset data yang besar dikembalikan. Tabel temp biasanya lebih cepat dalam hal ini.
HLGEM
1
@munissor, maka jangan gunakan fungsi bernilai tabel. Jika Anda ingin saran yang lebih baik, posting apa yang Anda lakukan.
HLGEM
-1

Variabel tabel terkadang lebih lambat karena tidak ada statistik pada variabel tabel, dan dengan demikian pengoptimal selalu mengasumsikan hanya satu catatan.

Namun saya tidak dapat menjamin bahwa ini adalah kasusnya di sini, Anda harus melihat pada informasi "perkiraan baris" dalam rencana kueri untuk variabel tabel.

halo yoel
sumber
Bagaimana hal itu memengaruhi insert ke dalam variabel tabel?
Martin Smith
Itulah yang tampaknya terjadi, karena Anda dapat melihat bahwa tidak hanya ada perbedaan antara paralel dan serial tetapi juga antara hash dan nested loop bergabung, tampaknya pengoptimal mengasumsikan bahwa karena variabel tabel menyimpan satu catatan dalam pikirannya maka hasilnya kueri juga akan menjadi satu rekaman, sekali lagi satu-satunya cara untuk membuktikannya adalah dengan melihat statistik aktual untuk setiap bagian dari kueri, tetapi kenyataannya adalah bahwa semua kueri yang melibatkan variabel tabel berakhir dengan loop bergabung dan pemrosesan serial, jadi saya pikir wajar untuk curiga di sini
yoel halb