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

Cache Objek Sementara SQL Server

Membuat tabel adalah operasi yang relatif intensif sumber daya dan memakan waktu. Server harus mencari dan mengalokasikan ruang penyimpanan untuk data baru dan struktur indeks, dan membuat entri yang sesuai dalam beberapa tabel metadata sistem. Semua pekerjaan ini harus dilakukan dengan cara yang akan selalu bekerja dengan benar di bawah konkurensi tinggi, dan yang memenuhi semua jaminan ACID yang diharapkan dari database relasional.

Di SQL Server, ini berarti mengambil jenis penguncian dan pengait yang tepat, dalam urutan yang benar, sambil juga memastikan bahwa entri log transaksi yang terperinci berkomitmen dengan aman ke penyimpanan persisten sebelum perubahan fisik apa pun ke database. Entri log ini memastikan sistem dapat mengembalikan database ke keadaan yang konsisten jika terjadi pembatalan transaksi atau sistem crash.

Menjatuhkan meja adalah operasi yang sama mahalnya. Untungnya, sebagian besar database tidak membuat atau menjatuhkan tabel dengan frekuensi tinggi. Pengecualian yang jelas untuk ini adalah database sistem tempdb . Basis data tunggal ini berisi penyimpanan fisik, struktur alokasi, metadata sistem, dan entri log transaksi untuk semua tabel sementara dan variabel tabel di seluruh instance SQL Server.

Ini adalah sifat tabel sementara dan variabel tabel yang akan dibuat dan dijatuhkan jauh lebih sering daripada tipe objek database lainnya. Ketika frekuensi penciptaan dan penghancuran yang tinggi secara alami ini digabungkan dengan efek pemusatan dari semua tabel sementara dan variabel tabel yang diasosiasikan dengan satu database, tidak mengherankan bahwa pertentangan dapat muncul dalam struktur alokasi dan metadata tempdb basis data.

Tembolok Objek Sementara

Untuk mengurangi dampak pada tempdb struktur, SQL Server dapat menyimpan objek sementara untuk digunakan kembali. Alih-alih menjatuhkan objek sementara, SQL Server mempertahankan metadata sistem, dan memotong data tabel. Jika tabel berukuran 8MB atau lebih kecil, pemotongan dilakukan secara serempak; jika tidak, drop yang ditangguhkan digunakan. Dalam kedua kasus tersebut, pemotongan mengurangi kebutuhan penyimpanan menjadi satu halaman data (kosong), dan informasi alokasi ke satu halaman IAM.

Caching menghindari hampir semua alokasi dan biaya metadata untuk membuat objek sementara di lain waktu. Sebagai efek samping dari membuat lebih sedikit perubahan pada tempdb database daripada siklus penurunan dan pembuatan ulang penuh, cache objek sementara juga mengurangi jumlah pencatatan transaksi yang diperlukan.

Mencapai Caching

Variabel tabel dan tabel sementara lokal keduanya mampu di-cache. Agar memenuhi syarat untuk caching, tabel sementara atau variabel tabel lokal harus dibuat dalam modul:

  • Prosedur tersimpan (termasuk prosedur tersimpan sementara)
  • Pemicu
  • Fungsi bernilai tabel multi-pernyataan
  • Fungsi skalar yang ditentukan pengguna

Nilai kembalian dari fungsi bernilai tabel multi-pernyataan adalah variabel tabel, yang dapat di-cache dengan sendirinya. Parameter bernilai tabel (yang juga merupakan variabel tabel) dapat di-cache ketika parameter dikirim dari aplikasi klien, misalnya dalam kode .NET menggunakan SqlDbType.Structured . Saat pernyataan diparameterisasi, struktur parameter bernilai tabel hanya dapat di-cache di SQL Server 2012 atau yang lebih baru.

Berikut tidak bisa di-cache:

  • Tabel sementara global
  • Objek dibuat menggunakan SQL ad-hoc
  • Objek dibuat menggunakan SQL dinamis (misalnya menggunakan EXECUTE atau sys.sp_executesql )

Untuk di-cache, objek sementara juga tidak boleh :

  • Memiliki batasan bernama (batasan tanpa nama eksplisit tidak masalah)
  • Lakukan "DDL" setelah pembuatan objek
  • Berada dalam modul yang ditentukan menggunakan WITH RECOMPILE pilihan
  • Dipanggil menggunakan WITH RECOMPILE pilihan EXECUTE pernyataan

Untuk mengatasi beberapa kesalahpahaman umum secara eksplisit:

  • TRUNCATE TABLE tidak mencegah caching
  • DROP TABLE tidak mencegah caching
  • UPDATE STATISTICS tidak mencegah caching
  • Pembuatan statistik otomatis tidak mencegah caching
  • Manual CREATE STATISTICS akan mencegah caching

Semua objek sementara dalam modul dinilai untuk kesesuaian caching secara terpisah. Modul yang berisi satu atau lebih objek sementara yang tidak dapat di-cache mungkin masih memenuhi syarat untuk cache objek sementara lainnya dalam modul yang sama.

Pola umum yang menonaktifkan caching untuk tabel sementara adalah pembuatan indeks setelah pernyataan pembuatan tabel awal. Dalam kebanyakan kasus, ini dapat diselesaikan dengan menggunakan kunci utama dan batasan unik. Di SQL Server 2014 dan yang lebih baru, kami memiliki opsi untuk menambahkan indeks non-clustered non-unik secara langsung dalam pernyataan pembuatan tabel menggunakan INDEX klausa.

Pemantauan dan Pemeliharaan

Kita dapat melihat berapa banyak objek sementara yang saat ini di-cache menggunakan penghitung cache DMV:

SELECT DOMCC.[type], DOMCC.pages_kb, DOMCC.pages_in_use_kb, DOMCC.entries_count, DOMCC.entries_in_use_countFROM sys.dm_os_memory_cache_counters SEBAGAI DOMCC WHERE DOMCC.[name] =N'Tabel Sementara &
 Contoh hasil adalah:

Entri cache dianggap sedang digunakan selama ada bagian dari modul yang berisi sedang dieksekusi. Eksekusi bersamaan dari modul yang sama akan menghasilkan beberapa objek sementara yang di-cache. Beberapa rencana eksekusi untuk modul yang sama (mungkin karena sesi yang berbeda SET options) juga akan menghasilkan beberapa entri cache untuk modul yang sama.

Entri cache dapat berkurang seiring waktu sebagai respons terhadap kebutuhan memori yang bersaing. Objek sementara yang di-cache juga dapat dihapus (secara asinkron, oleh utas sistem latar belakang) ketika rencana eksekusi modul induk dihapus dari cache rencana.

Meskipun tidak didukung (atau dengan cara apa pun direkomendasikan) untuk sistem produksi, penyimpanan cache objek sementara dapat sepenuhnya dihapus secara manual untuk tujuan pengujian dengan:

DBCC FREESYSTEMCACHE('Tabel Sementara &Variabel Tabel') WITH MARK_IN_USE_FOR_REMOVAL;WAITFOR DELAY '00:00:05';

Penundaan lima detik memungkinkan waktu untuk menjalankan tugas pembersihan latar belakang. Perhatikan bahwa perintah ini sebenarnya berbahaya . Anda hanya boleh menggunakannya (dengan risiko Anda sendiri) pada instance pengujian yang akses eksklusifnya Anda miliki. Setelah Anda selesai menguji, mulai ulang instance SQL Server.

Detail Implementasi Caching

Variabel tabel diimplementasikan oleh tabel pengguna 'nyata' di tempdb database (meskipun bukan tabel yang dapat kita kueri secara langsung). Nama tabel terkait adalah "#" diikuti oleh delapan digit representasi heksadesimal dari id objek. Kueri berikut menunjukkan hubungannya:

-- Sebuah tabel variabelDECLARE @Z AS tabel (z integer NULL); -- Entri sys.tables yang sesuaiSELECT T.[name], ObjIDFromName =CONVERT(integer, CONVERT(binary(4), RIGHT(T.[name], 8), 2)), T.[object_id], T.[ type_desc], T.create_date, T.modify_dateFROM tempdb.sys.tables AS T WHERE T.[name] LIKE N'#[0-9A-F][0-9A-F][0-9A-F][0 -9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]';

Hasil sampel ditunjukkan di bawah ini. Perhatikan bagaimana id objek yang dihitung dari nama objek cocok dengan id objek sebenarnya:

Menjalankan skrip tersebut sebagai SQL ad-hoc akan menghasilkan tempdb . yang berbeda ID objek (dan nama objek) pada setiap eksekusi (tanpa caching). Menempatkan skrip yang sama di dalam modul (misalnya, prosedur tersimpan) akan memungkinkan variabel tabel di-cache (selama SQL dinamis tidak digunakan), sehingga ID objek dan nama akan sama pada setiap eksekusi.

Ketika variabel tabel tidak di-cache, tabel yang mendasari dibuat dan dijatuhkan setiap kali. Saat cache objek sementara diaktifkan, tabel akan terpotong di akhir modul, bukan dibuang. Tidak ada tidak ada perubahan ke metadata sistem ketika variabel tabel di-cache. Dampak pada struktur alokasi dan pencatatan transaksi terbatas pada penghapusan baris dalam tabel dan penghapusan data berlebih dan halaman alokasi saat modul berakhir.

Tabel Sementara

Ketika tabel sementara digunakan sebagai pengganti variabel tabel, mekanisme dasarnya pada dasarnya sama, hanya dengan beberapa langkah penggantian nama tambahan:Ketika tabel sementara tidak di-cache , itu terlihat di tempdb dengan nama yang disediakan pengguna yang sudah dikenal, diikuti oleh sekelompok garis bawah dan representasi heksadesimal dari id objek sebagai akhiran akhir. Tabel sementara lokal tetap ada sampai secara eksplisit dijatuhkan, atau sampai lingkup pembuatannya berakhir. Untuk SQL ad-hoc, ini berarti saat sesi terputus dari server.

Untuk tabel sementara yang di-cache , pertama kali modul dijalankan, tabel sementara dibuat seperti halnya untuk kasus yang tidak di-cache. Di akhir modul, alih-alih dijatuhkan secara otomatis (saat cakupan pembuatannya berakhir), tabel sementara dipotong dan kemudian diganti namanya ke representasi heksadesimal dari ID objek (persis seperti yang terlihat untuk variabel tabel). Saat berikutnya modul berjalan, tabel yang di-cache diganti namanya dari format heksadesimal ke nama yang disediakan pengguna (ditambah garis bawah ditambah id objek hex).

Operasi penggantian nama tambahan di awal dan akhir modul melibatkan sejumlah kecil perubahan metadata sistem . Tabel sementara yang di-cache karena itu masih dapat mengalami setidaknya beberapa pertentangan metadata di bawah tingkat penggunaan kembali yang sangat tinggi. Namun demikian, dampak metadata dari tabel sementara yang di-cache jauh lebih rendah daripada kasus yang tidak di-cache (membuat dan menghapus tabel setiap kali).

Detail lebih lanjut dan contoh cara kerja cache objek sementara dapat ditemukan di artikel saya sebelumnya.

Statistik pada tabel sementara yang di-cache

Seperti disebutkan sebelumnya, statistik mungkin secara otomatis dibuat pada tabel sementara tanpa kehilangan keuntungan dari cache objek sementara (sebagai pengingat, membuat statistik secara manual akan nonaktifkan caching).

Peringatan penting adalah bahwa statistik terkait dengan tabel sementara yang di-cache tidak disetel ulang ketika objek di-cache di akhir modul, atau ketika objek yang di-cache diambil dari cache di awal modul. Akibatnya, statistik pada tabel sementara yang di-cache mungkin tertinggal dari eksekusi sebelumnya yang tidak terkait. Dengan kata lain, statistik mungkin sama sekali tidak ada hubungannya ke isi tabel sementara saat ini.

Ini jelas tidak diinginkan, mengingat alasan utama untuk memilih tabel sementara lokal daripada variabel tabel adalah ketersediaan statistik distribusi yang akurat. Dalam mitigasi, statistik akan diperbarui secara otomatis ketika (jika) jumlah akumulasi perubahan pada objek cache yang mendasarinya mencapai Ambang Kompilasi Ulang internal. Ini sulit untuk dinilai sebelumnya, karena detailnya rumit dan agak berlawanan dengan intuisi.

Solusi paling komprehensif, sambil mempertahankan manfaat dari cache objek sementara, adalah:

  • Secara manual UPDATE STATISTICS di meja sementara di dalam modul; dan
  • Tambahkan OPTION (RECOMPILE) petunjuk ke pernyataan yang mereferensikan tabel sementara

Tentu ada biaya yang terlibat dalam melakukan ini, tetapi ini paling sering dapat diterima. Memang, dengan memilih untuk menggunakan tabel sementara lokal di tempat pertama, penulis modul secara implisit mengatakan bahwa pemilihan rencana cenderung sensitif terhadap isi tabel sementara, sehingga kompilasi ulang dapat masuk akal. Memperbarui statistik secara manual memastikan bahwa statistik yang digunakan selama kompilasi ulang mencerminkan isi tabel saat ini (seperti yang pasti kita harapkan).

Untuk detail lebih lanjut tentang cara kerjanya, silakan lihat artikel saya sebelumnya tentang topik ini.

Ringkasan dan Rekomendasi

Caching objek sementara dalam modul dapat sangat mengurangi tekanan pada alokasi bersama dan struktur metadata di tempdb basis data. Pengurangan terbesar akan terjadi saat menggunakan variabel tabel karena caching dan penggunaan kembali objek sementara ini tidak melibatkan modifikasi metadata sama sekali (tidak ada operasi penggantian nama). Perselisihan pada struktur alokasi mungkin masih terlihat jika halaman data cache tunggal tidak cukup untuk menampung semua data variabel tabel saat runtime.

Dampak pada kualitas rencana karena kurangnya informasi kardinalitas untuk variabel tabel dapat dikurangi dengan menggunakan OPTION(RECOMPILE) atau melacak bendera 2453 (tersedia dari SQL Server 2012 dan seterusnya). Perhatikan bahwa mitigasi ini hanya memberikan informasi pengoptimal tentang jumlah total baris dalam tabel.

Untuk menggeneralisasi, variabel tabel paling baik digunakan ketika datanya kecil (idealnya pas dalam satu halaman data untuk manfaat pertikaian maksimum) dan ketika pemilihan paket tidak bergantung pada nilai yang ada dalam variabel tabel.

Jika informasi tentang distribusi data (densitas dan histogram) penting untuk pemilihan rencana, gunakan tabel sementara lokal sebagai gantinya. Pastikan untuk memenuhi ketentuan untuk cache tabel sementara, yang paling sering berarti tidak membuat indeks atau statistik setelah pernyataan pembuatan tabel awal. Ini dibuat lebih nyaman dari SQL Server 2014 dan seterusnya karena pengenalan INDEX klausa dari CREATE TABLE penyataan.

UPDATE STATISTICS explicit yang eksplisit setelah data dimuat ke tabel sementara, dan OPTION (RECOMPILE) petunjuk tentang pernyataan yang mereferensikan tabel mungkin diperlukan untuk menghasilkan semua manfaat yang diharapkan dari tabel sementara yang di-cache dalam sebuah modul.

Penting untuk hanya menggunakan objek sementara ketika objek tersebut menghasilkan manfaat yang jelas, paling sering dalam hal kualitas rencana. Penggunaan objek sementara yang berlebihan, tidak efisien, atau tidak perlu dapat menyebabkan tempdb pertentangan, bahkan ketika cache objek sementara tercapai.

Caching objek sementara yang optimal mungkin tidak cukup untuk mengurangi tempdb pertentangan ke tingkat yang dapat diterima dalam semua kasus, bahkan di mana objek sementara hanya digunakan ketika sepenuhnya dibenarkan. Menggunakan variabel tabel dalam memori atau tabel dalam memori yang tidak tahan lama dapat memberikan solusi yang ditargetkan dalam kasus seperti itu, meskipun selalu ada kompromi yang harus dibuat, dan saat ini tidak ada solusi tunggal yang mewakili opsi terbaik dalam semua kasus.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kunci Komposit Unik SQL Server dari Dua Bidang Dengan Peningkatan Otomatis Bidang Kedua

  2. Pagination di SQL Server menggunakan OFFSET/FETCH

  3. Kesalahan SQL Server 113:Tanda komentar akhir hilang '*/'

  4. Matikan kendala sementara (MS SQL)

  5. Subquery menggunakan Exists 1 atau Exists *