Di SQL Server 2005, kita bisa membuat tabel temp salah satu dari dua cara:
declare @tmp table (Col1 int, Col2 int);
atau
create table #tmp (Col1 int, Col2 int);
Apa perbedaan antara keduanya? Saya telah membaca pendapat yang bertentangan tentang apakah @tmp masih menggunakan tempdb, atau jika semuanya terjadi dalam memori.
Dalam skenario mana salah satu melakukan yang lainnya?
sql-server
temp-tables
table-variable
Eric Z Beard
sumber
sumber
Jawaban:
Ada beberapa perbedaan antara Tabel Sementara (#tmp) dan Tabel Variabel (@tmp), meskipun menggunakan tempdb bukan salah satunya, sebagaimana dijabarkan dalam tautan MSDN di bawah ini.
Sebagai pedoman praktis, untuk volume data kecil dan menengah dan skenario penggunaan sederhana, Anda harus menggunakan variabel tabel. (Ini adalah pedoman yang terlalu luas dengan tentu saja banyak pengecualian - lihat di bawah dan artikel berikut.)
Beberapa hal yang perlu dipertimbangkan ketika memilih di antara mereka:
Tabel Sementara adalah tabel nyata sehingga Anda dapat melakukan hal-hal seperti BUAT INDEKS, dll. Jika Anda memiliki sejumlah besar data yang mengakses dengan indeks lebih cepat maka tabel sementara adalah pilihan yang baik.
Variabel tabel dapat memiliki indeks dengan menggunakan kendala PRIMARY KEY atau UNIK. (Jika Anda ingin indeks non-unik cukup sertakan kolom kunci utama sebagai kolom terakhir dalam batasan unik. Jika Anda tidak memiliki kolom unik, Anda dapat menggunakan kolom identitas.) SQL 2014 juga memiliki indeks tidak unik .
Variabel tabel tidak berpartisipasi dalam transaksi dan
SELECT
secara implisit denganNOLOCK
. Perilaku transaksi bisa sangat membantu, misalnya jika Anda ingin ROLLBACK di tengah prosedur maka variabel tabel yang diisi selama transaksi itu masih akan diisi!Tabel temp dapat menghasilkan prosedur tersimpan yang dikompilasi ulang, mungkin sering. Variabel tabel tidak akan.
Anda bisa membuat tabel temp menggunakan SELECT INTO, yang bisa lebih cepat untuk menulis (baik untuk permintaan ad-hoc) dan memungkinkan Anda untuk berurusan dengan mengubah tipe data dari waktu ke waktu, karena Anda tidak perlu menentukan struktur tabel temp Anda di muka.
Anda bisa meneruskan variabel tabel kembali dari fungsi, memungkinkan Anda untuk merangkum dan menggunakan kembali logika jauh lebih mudah (misalnya membuat fungsi untuk membagi string menjadi tabel nilai pada beberapa pembatas yang berubah-ubah).
Menggunakan Tabel Variabel dalam fungsi-fungsi yang ditentukan pengguna memungkinkan fungsi-fungsi itu digunakan lebih luas (lihat CREATE FUNCTION dokumentasi untuk detailnya). Jika Anda menulis fungsi, Anda harus menggunakan variabel tabel di atas tabel temp kecuali jika ada kebutuhan yang mendesak.
Variabel tabel dan tabel temp disimpan dalam tempdb. Tetapi variabel tabel (sejak 2005) default untuk collation dari database saat ini versus temp tables yang mengambil collation default tempdb ( ref ). Ini berarti Anda harus mengetahui masalah pengumpulan jika menggunakan tabel temp dan pengumpulan db Anda berbeda dengan tempdb, yang menyebabkan masalah jika Anda ingin membandingkan data di tabel temp dengan data di database Anda.
Global Temp Tables (## tmp) adalah jenis tabel temp lainnya yang tersedia untuk semua sesi dan pengguna.
Beberapa bacaan lebih lanjut:
Jawaban hebat Martin Smith di dba.stackexchange.com
FAQ MSDN tentang perbedaan antara keduanya: https://support.microsoft.com/en-gb/kb/305977
Artikel blog MDSN: https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/tempdb-table-variable-vs-local-tentara-table-table
Artikel: https://searchsqlserver.techtarget.com/tip/T temporary-tables-in-SQL-Server-vs-table-variables
Perilaku yang tidak terduga dan implikasi kinerja tabel temp dan variabel temp: Paul White di SQLblog.com
sumber
Hanya dengan melihat klaim dalam jawaban yang diterima bahwa variabel tabel tidak berpartisipasi dalam pencatatan.
Secara umum tampaknya tidak benar bahwa ada perbedaan dalam jumlah penebangan (setidaknya untuk
insert
/update
/delete
operasi ke tabel itu sendiri meskipun saya sejak itu menemukan bahwa ada beberapa perbedaan kecil dalam hal ini untuk objek sementara di-cache dalam prosedur tersimpan karena tabel sistem tambahan pembaruan).Saya melihat perilaku logging terhadap a
@table_variable
dan#temp
tabel untuk operasi berikut.Catatan log transaksi hampir identik untuk semua operasi.
Versi variabel tabel sebenarnya memiliki beberapa entri log tambahan karena mendapat entri yang ditambahkan ke (dan kemudian dihapus dari)
sys.syssingleobjrefs
tabel dasar tetapi secara keseluruhan memiliki beberapa byte kurang dicatat murni sebagai nama internal untuk variabel tabel mengkonsumsi 236 byte lebih sedikit daripada untuk#temp
tabel (118nvarchar
karakter lebih sedikit ).Skrip lengkap untuk direproduksi (dijalankan terbaik pada contoh yang dimulai dalam mode pengguna tunggal dan menggunakan
sqlcmd
mode)Hasil
sumber
INSERT ... SELECT
tidak dicatat minimal dan Anda tidak bisaSELECT INTO ...
variabel tabel.Untuk tabel yang lebih kecil (kurang dari 1000 baris) gunakan variabel temp, jika tidak gunakan tabel temp.
sumber
@ wcm - sebenarnya untuk nit memilih Table Variable bukan hanya Ram - itu dapat disimpan sebagian pada disk.
Tabel temp dapat memiliki indeks, sedangkan variabel tabel hanya dapat memiliki indeks primer. Jika kecepatan masalah Tabel variabel bisa lebih cepat, tetapi jelas jika ada banyak catatan, atau kebutuhan untuk mencari tabel temp indeks berkerumun, maka Tabel Temp akan lebih baik.
Artikel latar belakang yang bagus
sumber
Temp table: Temp table mudah untuk membuat dan membuat cadangan data.
Variabel tabel: Tapi variabel tabel melibatkan upaya ketika kita biasanya membuat tabel normal.
Tabel temp: Hasil tabel temp dapat digunakan oleh banyak pengguna.
Variabel tabel: Tetapi variabel tabel hanya dapat digunakan oleh pengguna saat ini.
Temp table: Temp table akan disimpan di tempdb. Ini akan membuat lalu lintas jaringan. Ketika kita memiliki data besar di tabel temp maka itu harus bekerja di database. Masalah kinerja akan ada.
Variabel tabel: Tetapi variabel tabel akan menyimpan dalam memori fisik untuk beberapa data, kemudian nanti ketika ukurannya meningkat, akan dipindahkan ke tempdb.
Temp table: Temp table dapat melakukan semua operasi DDL. Memungkinkan membuat indeks, menjatuhkan, mengubah, dll.,
Variabel tabel: Sedangkan variabel tabel tidak akan memungkinkan melakukan operasi DDL. Tetapi variabel tabel memungkinkan kita untuk membuat hanya indeks berkerumun.
Temp table: Temp table dapat digunakan untuk sesi saat ini atau global. Sehingga sesi beberapa pengguna dapat memanfaatkan hasil dalam tabel.
Variabel tabel: Tetapi variabel tabel dapat digunakan hingga program itu. (Prosedur tersimpan)
Tabel temp: Variabel temp tidak dapat menggunakan transaksi. Ketika kita melakukan operasi DML dengan tabel temp maka itu bisa rollback atau melakukan transaksi.
Variabel tabel: Tapi kita tidak bisa melakukannya untuk variabel tabel.
Tabel temp: Fungsi tidak dapat menggunakan variabel temp. Terlebih lagi kita tidak bisa melakukan operasi DML dalam fungsi.
Variabel tabel: Tetapi fungsi memungkinkan kita untuk menggunakan variabel tabel. Tetapi menggunakan variabel tabel kita bisa melakukan itu.
Tabel temp: Prosedur tersimpan akan melakukan kompilasi ulang (tidak dapat menggunakan rencana eksekusi yang sama) saat kami menggunakan variabel temp untuk setiap panggilan sub sekuensial.
Variabel tabel: Sedangkan variabel tabel tidak akan melakukan seperti itu.
sumber
Untuk Anda semua yang percaya mitos bahwa variabel temp hanya dalam memori
Pertama, variabel tabel TIDAK harus residen memori. Di bawah tekanan memori, halaman milik variabel tabel dapat didorong keluar ke tempdb.
Baca artikel di sini: TempDB :: Tabel variabel vs tabel sementara lokal
sumber
Perbedaan utama lainnya adalah variabel tabel tidak memiliki statistik kolom, seperti halnya tabel temp. Ini berarti bahwa optimizer kueri tidak tahu berapa banyak baris dalam variabel tabel (tebakan 1), yang dapat menyebabkan rencana yang sangat tidak optimal dihasilkan jika variabel tabel sebenarnya memiliki sejumlah besar baris.
sumber
rows
kolomsys.partitions
dipertahankan untuk variabel meja sehingga tidak benar-benar tahu berapa banyak baris dalam tabel. Ini bisa dilihat dengan menggunakanOPTION (RECOMPILE)
. Tetapi kurangnya statistik kolom berarti tidak dapat memperkirakan predikat kolom tertentu.Kutipan diambil dari; Profesional SQL Server 2012 Internal dan Pemecahan Masalah
VARIABEL TABEL TIDAK DICIPTAKAN DALAM MEMORI
Ada kesalahpahaman umum bahwa variabel tabel adalah struktur di-memori dan dengan demikian akan melakukan lebih cepat daripada tabel sementara . Berkat DMV yang disebut sys. dm _ db _ session _ spasi _ penggunaan, yang menunjukkan penggunaan tempdb per sesi, Anda dapat membuktikan bahwa bukan itu masalahnya . Setelah memulai ulang SQL Server untuk menghapus DMV, jalankan skrip berikut untuk mengonfirmasi bahwa sesi Anda _ id mengembalikan 0 untuk pengguna _ objek _ mengalokasikan _ halaman _ menghitung:
Sekarang Anda dapat memeriksa berapa banyak ruang yang digunakan tabel sementara dengan menjalankan skrip berikut untuk membuat tabel sementara dengan satu kolom dan mengisinya dengan satu baris:
Hasil di server saya menunjukkan bahwa tabel dialokasikan satu halaman di tempdb. Sekarang jalankan skrip yang sama tetapi gunakan variabel tabel kali ini:
Yang mana yang akan digunakan?
sumber
Perbedaan lain:
Tabel var hanya dapat diakses dari pernyataan di dalam prosedur yang membuatnya, bukan dari prosedur lain yang dipanggil oleh prosedur itu atau bersarang SQL dinamis (via exec atau sp_executesql).
Ruang lingkup tabel temp, di sisi lain, termasuk kode dalam prosedur yang disebut dan SQL dinamis bersarang.
Jika tabel yang dibuat oleh prosedur Anda harus dapat diakses dari prosedur lain yang disebut atau SQL dinamis, Anda harus menggunakan tabel temp. Ini bisa sangat berguna dalam situasi yang kompleks.
sumber
Perbedaan antara
Temporary Tables (##temp/#temp)
danTable Variables (@table)
adalah sebagai:Table variable (@table)
dibuat dimemory
. Sedangkan,Temporary table (##temp/#temp)
dibuat ditempdb database
. Namun, jika ada tekanan memori halaman-halaman yang termasuk variabel tabel dapat didorong ke tempdb.Table variables
tidak dapat terlibat dalamtransactions, logging or locking
. Ini membuat@table faster then #temp
. Jadi variabel tabel lebih cepat daripada tabel sementara.Temporary table
memungkinkan modifikasi Skema tidak sepertiTable variables
.Temporary tables
terlihat dalam rutinitas yang dibuat dan juga dalam rutinitas anak. Sedangkan, variabel Tabel hanya terlihat dalam rutin yang dibuat.Temporary tables
diizinkanCREATE INDEXes
sedangkan,Table variables
tidak diizinkanCREATE INDEX
sebaliknya mereka dapat memiliki indeks dengan menggunakanPrimary Key or Unique Constraint
.sumber
Pertimbangkan juga bahwa Anda sering dapat mengganti keduanya dengan tabel turunan yang mungkin lebih cepat juga. Seperti semua penyetelan kinerja, hanya tes yang sebenarnya terhadap data aktual Anda yang dapat memberi tahu Anda pendekatan terbaik untuk permintaan khusus Anda.
sumber
Itu mengejutkan saya bahwa tidak ada yang menyebutkan perbedaan utama antara keduanya adalah bahwa tabel temp mendukung dukungan paralel sementara variabel tabel tidak. Anda harus dapat melihat perbedaan dari rencana eksekusi. Dan inilah video dari SQL Workshops di Channel 9 .
Ini juga menjelaskan mengapa Anda harus menggunakan variabel temp untuk tabel yang lebih kecil, jika tidak gunakan tabel temp, seperti yang dijawab SQLMenace sebelumnya.
sumber