Saya belajar lebih detail dalam variabel tabel. Dikatakan bahwa tabel temp selalu di disk, dan variabel tabel ada di memori, artinya, kinerja variabel tabel lebih baik daripada tabel temp karena variabel tabel menggunakan lebih sedikit operasi IO daripada tabel temp.
Tetapi kadang-kadang, jika ada terlalu banyak catatan dalam variabel tabel yang tidak dapat terkandung dalam memori, variabel tabel akan diletakkan di disk seperti tabel temp.
Tapi saya tidak tahu apa "terlalu banyak catatan" itu. 100.000 catatan? atau 1000.000 catatan? Bagaimana saya bisa tahu jika variabel tabel yang saya gunakan ada di memori atau ada di disk? Apakah ada fungsi atau alat di SQL Server 2005 untuk mengukur skala variabel tabel atau memberi tahu saya ketika variabel tabel diletakkan di disk dari memori?
tempDB
- bahwa "dalam memori" adalah mitos. Juga: variabel tabel akan selalu dianggap oleh pengoptimal kueri untuk memegang tepat satu baris - jika Anda memiliki lebih banyak baris, ini dapat menyebabkan rencana eksekusi yang sangat buruk.tempdb
(tetapi mungkin juga sepenuhnya dalam memori)Jawaban:
Pertanyaan Anda menunjukkan Anda telah menyerah pada beberapa kesalahpahaman umum seputar variabel tabel dan tabel sementara.
Saya telah menulis jawaban yang cukup luas di situs DBA melihat perbedaan antara kedua jenis objek. Ini juga menjawab pertanyaan Anda tentang disk vs memori (saya tidak melihat perbedaan perilaku yang signifikan antara keduanya).
Mengenai pertanyaan dalam judul meskipun kapan menggunakan variabel tabel vs tabel sementara lokal Anda tidak selalu punya pilihan. Dalam fungsi, misalnya, hanya mungkin untuk menggunakan variabel tabel dan jika Anda perlu menulis ke tabel dalam lingkup anak maka hanya
#temp
tabel yang akan melakukannya (parameter bernilai tabel memungkinkan akses hanya baca ).Di mana Anda memiliki pilihan, beberapa saran ada di bawah ini (meskipun metode yang paling dapat diandalkan adalah dengan hanya menguji keduanya dengan beban kerja spesifik Anda).
Jika Anda memerlukan indeks yang tidak dapat dibuat pada variabel tabel maka tentu saja Anda akan membutuhkan
#temporary
tabel. Namun rincian ini tergantung pada versi. Untuk SQL Server 2012 dan di bawah ini satu-satunya indeks yang dapat dibuat pada variabel tabel adalah mereka yang secara implisit dibuat melaluiUNIQUE
atauPRIMARY KEY
kendala. SQL Server 2014 memperkenalkan sintaks indeks sebaris untuk subset dari opsi yang tersedia diCREATE INDEX
. Ini telah diperpanjang sejak untuk memungkinkan kondisi indeks yang difilter. Indeks denganINCLUDE
-d kolom atau indeks kolomstore masih tidak memungkinkan untuk membuat variabel tabel.Jika Anda akan berulang kali menambahkan dan menghapus banyak baris dari tabel maka gunakan
#temporary
tabel. Itu mendukungTRUNCATE
(yang lebih efisien daripadaDELETE
untuk tabel besar) dan tambahan menyisipkan berikutTRUNCATE
dapat memiliki kinerja yang lebih baik daripada yang mengikutiDELETE
seperti yang diilustrasikan di sini .#temporary
tabel. Itu mendukung pembuatan statistik yang memungkinkan rencana untuk dikompilasi ulang secara dinamis sesuai dengan data (meskipun untuk tabel sementara cache dalam prosedur tersimpan , perilaku kompilasi perlu dipahami secara terpisah).SELECT
pernyataan yang berpotensi mahal maka pertimbangkan bahwa menggunakan variabel tabel akan memblokir kemungkinan ini menggunakan rencana paralel.#temp
tabel dalam transaksi pengguna kunci dapat ditahan lebih lama dari untuk variabel tabel (berpotensi sampai akhir transaksi vs akhir pernyataan tergantung pada jenis kunci dan tingkat isolasi) dan juga dapat mencegah pemotongantempdb
log transaksi hingga transaksi pengguna berakhir. Jadi ini mungkin mendukung penggunaan variabel tabel.#temporary
tabel. Bob Ward menunjukkan dalamtempdb
presentasinya bahwa ini dapat menyebabkan pertikaian tambahan pada tabel sistem dalam kondisi konkurensi tinggi. Selain itu, ketika berhadapan dengan sejumlah kecil data, ini dapat membuat perbedaan terukur untuk kinerja .Efek berbagi rowset
sumber
id
dan penggunaanOPTION (RECOMPILE)
mungkin akan baik untuk itu - tetapi uji keduanya.Gunakan variabel tabel jika untuk jumlah data yang sangat kecil (ribuan byte)
Gunakan tabel sementara untuk banyak data
Cara lain untuk memikirkannya: jika Anda berpikir Anda mungkin mendapat manfaat dari indeks, statistik otomatis, atau kebaikan pengoptimal SQL, maka kumpulan data Anda mungkin terlalu besar untuk variabel tabel.
Dalam contoh saya, saya hanya ingin menempatkan sekitar 20 baris ke dalam format dan memodifikasinya sebagai grup, sebelum menggunakannya untuk MEMPERBARUI / MEMASANG tabel permanen. Jadi variabel tabel sempurna.
Tapi saya juga menjalankan SQL untuk mengisi kembali ribuan baris sekaligus, dan saya pasti bisa mengatakan bahwa tabel sementara berkinerja lebih baik daripada variabel tabel.
Ini tidak berbeda dengan bagaimana CTE menjadi perhatian karena alasan ukuran yang sama - jika data dalam CTE sangat kecil, saya menemukan CTE berkinerja sebaik atau lebih baik dari apa yang dihasilkan oleh pengoptimal, tetapi jika itu cukup besar maka itu menyakitkan kamu buruk.
Pemahaman saya sebagian besar didasarkan pada http://www.developerfusion.com/article/84397/table-variables-v-turnal-tables-in-sql-server/ , yang memiliki lebih banyak detail.
sumber
Microsoft mengatakan di sini
sumber
Saya sepenuhnya setuju dengan Abacus (maaf - tidak punya cukup poin untuk berkomentar).
Juga, perlu diingat bahwa itu tidak selalu turun ke berapa banyak catatan yang Anda miliki, tetapi ukuran catatan Anda.
Misalnya, apakah Anda mempertimbangkan perbedaan kinerja antara 1.000 catatan dengan 50 kolom masing-masing vs 100.000 catatan dengan hanya 5 kolom masing-masing?
Terakhir, mungkin Anda meminta / menyimpan lebih banyak data daripada yang Anda butuhkan? Berikut ini bacaan yang bagus tentang strategi optimasi SQL . Batasi jumlah data yang Anda tarik, terutama jika Anda tidak menggunakan semuanya (beberapa pemrogram SQL menjadi malas dan hanya memilih semuanya meskipun mereka hanya menggunakan sebagian kecil). Jangan lupa penganalisa query SQL juga bisa menjadi teman terbaik Anda.
sumber
Tabel variabel hanya tersedia untuk sesi saat ini, misalnya, jika Anda perlu
EXEC
prosedur tersimpan lain dalam saat ini Anda harus melewati tabel karenaTable Valued Parameter
dan tentu saja ini akan mempengaruhi kinerja, dengan tabel sementara Anda dapat melakukan ini hanya dengan lewat nama tabel sementaraUntuk menguji tabel Sementara:
Untuk menguji tabel Variabel:
sesuatu yang lain yang saya alami adalah: Jika skema Anda tidak memiliki
GRANT
hak istimewa untuk membuat tabel maka gunakan tabel variabel.sumber
menulis data dalam tabel yang dideklarasikan
declare @tb
dan setelah bergabung dengan tabel lain, saya menyadari bahwa waktu respons dibandingkan dengan tabel sementaratempdb .. # tb
jauh lebih tinggi.Ketika saya bergabung dengan mereka dengan @tb , waktu jauh lebih lama untuk mengembalikan hasilnya, tidak seperti #tm , pengembaliannya hampir seketika.
Saya melakukan tes dengan 10.000 baris bergabung dan bergabung dengan 5 tabel lainnya
sumber