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

Kapan saya harus menggunakan variabel tabel vs tabel sementara di server sql?

Pertanyaan Anda menunjukkan bahwa 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 dua jenis objek. Ini juga menjawab pertanyaan Anda tentang disk vs memori (saya tidak melihat perbedaan perilaku yang signifikan di antara keduanya).

Mengenai pertanyaan dalam judul tentang kapan harus menggunakan variabel tabel vs tabel sementara lokal, Anda tidak selalu punya pilihan. Dalam fungsi, misalnya, hanya mungkin menggunakan variabel tabel dan jika Anda perlu menulis ke tabel dalam lingkup anak maka hanya #temp tabel akan melakukannya (parameter bernilai tabel memungkinkan akses hanya baca).

Jika Anda memiliki pilihan, beberapa saran ada di bawah (meskipun metode yang paling dapat diandalkan adalah dengan menguji keduanya dengan beban kerja spesifik Anda).

  1. Jika Anda memerlukan indeks yang tidak dapat dibuat pada variabel tabel maka Anda tentu memerlukan #temporary meja. Namun, detailnya bergantung pada versi. Untuk SQL Server 2012 dan di bawahnya, satu-satunya indeks yang dapat dibuat pada variabel tabel adalah yang dibuat secara implisit melalui UNIQUE atau PRIMARY KEY paksaan. SQL Server 2014 memperkenalkan sintaks indeks sebaris untuk subset opsi yang tersedia di CREATE INDEX . Ini telah diperpanjang sejak untuk memungkinkan kondisi indeks yang difilter. Indeks dengan INCLUDE -d kolom atau indeks columnstore masih tidak mungkin dibuat pada variabel tabel.

  2. Jika Anda akan berulang kali menambahkan dan menghapus sejumlah besar baris dari tabel, gunakan #temporary meja. Itu mendukung TRUNCATE (yang lebih efisien daripada DELETE untuk tabel besar) dan tambahan penyisipan berikutnya mengikuti TRUNCATE dapat memiliki kinerja yang lebih baik daripada yang mengikuti DELETE seperti yang diilustrasikan di sini.

  3. Jika Anda akan menghapus atau memperbarui sejumlah besar baris maka tabel temp mungkin berkinerja jauh lebih baik daripada variabel tabel - jika dapat menggunakan berbagi baris (lihat "Efek berbagi baris" di bawah untuk contoh) .
  4. Jika rencana optimal menggunakan tabel akan bervariasi tergantung pada data maka gunakan #temporary meja. Itu mendukung pembuatan statistik yang memungkinkan rencana untuk dikompilasi ulang secara dinamis sesuai dengan data (meskipun untuk tabel sementara yang di-cache dalam prosedur tersimpan, perilaku kompilasi ulang perlu dipahami secara terpisah).
  5. Jika rencana optimal untuk kueri menggunakan tabel kemungkinan tidak akan pernah berubah, Anda dapat mempertimbangkan variabel tabel untuk melewati overhead pembuatan statistik dan kompilasi ulang (mungkin memerlukan petunjuk untuk memperbaiki rencana yang Anda inginkan).
  6. Jika sumber data yang dimasukkan ke tabel berasal dari SELECT . yang berpotensi mahal pernyataan kemudian pertimbangkan bahwa menggunakan variabel tabel akan memblokir kemungkinan ini menggunakan rencana paralel.
  7. Jika Anda memerlukan data dalam tabel untuk bertahan dari rollback transaksi pengguna luar, gunakan variabel tabel. Kemungkinan kasus penggunaan untuk ini mungkin mencatat kemajuan langkah-langkah yang berbeda dalam kumpulan SQL yang panjang.
  8. Saat menggunakan #temp tabel dalam kunci transaksi pengguna dapat disimpan lebih lama daripada variabel tabel (berpotensi hingga akhir transaksi vs akhir pernyataan tergantung pada jenis kunci dan tingkat isolasi) dan juga dapat mencegah pemotongan tempdb log transaksi sampai transaksi pengguna berakhir. Jadi ini mungkin mendukung penggunaan variabel tabel.
  9. Dalam rutinitas yang tersimpan, variabel tabel dan tabel sementara dapat di-cache. Pemeliharaan metadata untuk variabel tabel yang di-cache kurang dari itu untuk #temporary tabel. Bob Ward menunjukkan dalam tempdb-nya presentasi bahwa ini dapat menyebabkan pertentangan tambahan pada tabel sistem dalam kondisi konkurensi tinggi. Selain itu, saat menangani data dalam jumlah kecil, hal ini dapat membuat perbedaan kinerja yang terukur.

Efek berbagi baris baris

DECLARE @T TABLE(id INT PRIMARY KEY, Flag BIT);

CREATE TABLE #T (id INT PRIMARY KEY, Flag BIT);

INSERT INTO @T 
output inserted.* into #T
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY @@SPID), 0
FROM master..spt_values v1, master..spt_values v2

SET STATISTICS TIME ON

/*CPU time = 7016 ms,  elapsed time = 7860 ms.*/
UPDATE @T SET Flag=1;

/*CPU time = 6234 ms,  elapsed time = 7236 ms.*/
DELETE FROM @T

/* CPU time = 828 ms,  elapsed time = 1120 ms.*/
UPDATE #T SET Flag=1;

/*CPU time = 672 ms,  elapsed time = 980 ms.*/
DELETE FROM #T

DROP TABLE #T


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. String Format Numerik Kustom Didukung oleh FORMAT() di SQL Server

  2. Apa itu LEN() di SQL Server?

  3. Cara Mengubah Susunan Database SQL Server menggunakan T-SQL

  4. Bagaimana cara mengatur pemeriksaan untuk koneksi di SQL Server?

  5. TABLOCK vs TABLOCKX