Ukuran Tabel dan Baris dalam Tabel Memory-Optimized

Tabel yang dioptimalkan memori terdiri dari kumpulan baris dan indeks yang berisi pointer ke baris. Dalam tabel yang dioptimalkan memori, baris tidak boleh lebih panjang dari 8.060 byte. Memahami ukuran tabel yang dioptimalkan memori akan membantu Anda memahami apakah komputer Anda memiliki cukup memori.

Ada dua alasan untuk menghitung tabel dan ukuran baris:

  • Berapa banyak memori yang digunakan tabel?

    • Jumlah memori yang digunakan oleh tabel tidak dapat dihitung dengan tepat. Banyak faktor yang memengaruhi jumlah memori yang digunakan. Faktor-faktor seperti alokasi memori berbasis halaman, lokalitas, penembolokan, dan padding. Selain itu, beberapa versi baris yang memiliki transaksi aktif yang terkait atau yang menunggu pengumpulan sampah.

    • Ukuran minimum yang diperlukan untuk data dan indeks dalam tabel diberikan oleh perhitungan untuk [ukuran tabel], dibahas di bawah ini.

    • Menghitung penggunaan memori adalah perkiraan terbaik dan Anda disarankan untuk menyertakan perencanaan kapasitas dalam rencana penyebaran Anda.

  • Ukuran data baris, dan apakah sesuai dengan batasan ukuran baris 8.060 byte? Untuk menjawab pertanyaan-pertanyaan ini, gunakan komputasi untuk [ukuran isi baris], yang dibahas di bawah ini.

Gambar berikut mengilustrasikan tabel dengan indeks dan baris, yang pada gilirannya memiliki header dan isi baris:

Tabel memori yang dioptimalkan.
Tabel yang dioptimalkan memori, terdiri dari indeks dan baris.

Ukuran dalam memori tabel, dalam byte, dihitung sebagai berikut:

[table size] = [size of index 1] + ... + [size of index n] + ([row size] * [row count])  

Ukuran indeks hash diperbaiki pada waktu pembuatan tabel dan tergantung pada jumlah wadah aktual. Bucket_count yang ditentukan dengan spesifikasi indeks dibulatkan ke atas ke daya terdekat 2 untuk mendapatkan [jumlah wadah aktual]. Misalnya, jika bucket_count yang ditentukan adalah 100000, [jumlah wadah aktual] untuk indeks 131072.

[hash index size] = 8 * [actual bucket count]  

Ukuran baris dihitung dengan menambahkan header dan isi:

[row size] = [row header size] + [actual row body size]  
[row header size] = 24 + 8 * [number of indices]  

Ukuran isi baris

Perhitungan [ukuran isi baris] dibahas dalam tabel berikut.

Ada dua komputasi berbeda untuk ukuran isi baris: ukuran komputasi dan ukuran aktual:

  • Ukuran komputasi, ditandai dengan [ukuran isi baris komputasi], digunakan untuk menentukan apakah batasan ukuran baris 8.060 byte terlampaui.

  • Ukuran aktual, yang ditandai dengan [ukuran isi baris aktual], adalah ukuran penyimpanan aktual dari isi baris dalam memori dan dalam file titik pemeriksaan.

Baik [ukuran isi baris komputasi] dan [ukuran isi baris aktual] dihitung serupa. Satu-satunya perbedaan adalah perhitungan ukuran kolom (n)varchar(i) dan varbinary(i), seperti yang tercermin di bagian bawah tabel berikut. Ukuran isi baris yang dikomputasi menggunakan ukuran yang dideklarasikan i sebagai ukuran kolom, sementara ukuran isi baris aktual menggunakan ukuran data yang sebenarnya.

Tabel berikut menjelaskan perhitungan ukuran isi baris, yang diberikan sebagai [ukuran isi baris aktual] = SUM([ukuran jenis dangkal]) + 2 + 2 * [jumlah kolom tipe dalam].

Bagian Ukuran Komentar
Kolom jenis dangkal SUM([ukuran jenis dangkal])

Ukuran jenis individu adalah sebagai berikut:

Bit | 1

Tinyint | 1

Smallint | 2

Int | 4

Nyata | 4

Smalldatetime | 4

Smallmoney | 4

Bigint | 8

Tanggalwaktu | 8

Datetime2 | 8

Float 8

Uang 8

Numerik (presisi <=18) | 8

Waktu | 8

Numerik(presisi>18) | 16

Pengidentifikasi unik | 16
Padding kolom dangkal Potensi nilai:

1 jika ada kolom jenis dalam dan ukuran data total kolom dangkal adalah sebagai angka ganjil.

0 jika tidak
Jenis mendalam adalah jenis (var)biner dan (n)(var)char.
Array offset untuk kolom tipe dalam Potensi nilai:

0 jika tidak ada kolom tipe dalam

2 + 2 * [jumlah kolom tipe dalam] jika tidak
Jenis mendalam adalah jenis (var)biner dan (n)(var)char.
Array NULL [jumlah kolom nullable] / 8, dibulatkan ke atas hingga byte penuh. Array memiliki satu bit per kolom yang dapat diubah ke null. Ini dibulatkan ke atas hingga byte penuh.
Padding array NULL Potensi nilai:

1 jika ada kolom tipe dalam dan ukuran array NULL adalah jumlah byte ganjil.

0 jika tidak
Jenis mendalam adalah jenis (var)biner dan (n)(var)char.
Padding Jika tidak ada kolom tipe dalam: 0

Jika ada kolom jenis dalam, 0-7 byte padding ditambahkan, berdasarkan perataan terbesar yang diperlukan oleh kolom dangkal. Setiap kolom dangkal memerlukan perataan yang sama dengan ukurannya seperti yang didokumentasikan di atas, kecuali bahwa kolom GUID membutuhkan perataan 1 byte (bukan 16) dan kolom numerik selalu membutuhkan perataan 8 byte (tidak pernah 16). Persyaratan perataan terbesar di antara semua kolom dangkal digunakan, dan 0-7 byte padding ditambahkan singgahnya sehingga ukuran total sejauh ini (tanpa kolom jenis dalam) adalah kelipatan dari perataan yang diperlukan.
Jenis mendalam adalah jenis (var)biner dan (n)(var)char.
Kolom tipe dalam dengan panjang tetap SUM([ukuran kolom tipe dalam panjang tetap])

Ukuran setiap kolom adalah sebagai berikut:

i untuk char(i) dan biner(i).

2 * i untuk nchar(i)
Kolom tipe dalam dengan panjang tetap adalah kolom jenis char(i), nchar(i), atau biner(i).
Kolom tipe dalam panjang variabel [ukuran komputasi] SUM([ukuran komputasi kolom tipe dalam panjang variabel])

Ukuran komputasi setiap kolom adalah sebagai berikut:

i untuk varchar(i) dan varbinary(i)

2 * i untuk nvarchar(i)
Baris ini hanya diterapkan ke [ukuran isi baris komputasi].

Kolom tipe dalam dengan panjang variabel adalah kolom jenis varchar(i), nvarchar(i), atau varbinary(i). Ukuran komputasi ditentukan oleh panjang maksimum (i) kolom.
Kolom tipe dalam panjang variabel [ukuran aktual] SUM([ukuran aktual kolom tipe dalam panjang variabel])

Ukuran aktual setiap kolom adalah sebagai berikut:

n, di mana n adalah jumlah karakter yang disimpan dalam kolom, untuk varchar(i).

2 * n, di mana n adalah jumlah karakter yang disimpan dalam kolom, untuk nvarchar(i).

n, di mana n adalah jumlah byte yang disimpan dalam kolom, untuk varbinary(i).
Baris ini hanya diterapkan ke [ukuran isi baris aktual].

Ukuran aktual ditentukan oleh data yang disimpan dalam kolom di baris.

Struktur Baris

Baris dalam tabel yang dioptimalkan memori memiliki komponen berikut:

  • Header baris berisi tanda waktu yang diperlukan untuk menerapkan penerapan versi baris. Header baris juga berisi penunjuk indeks untuk mengimplementasikan rantai baris dalam wadah hash (dijelaskan di atas).

  • Isi baris berisi data kolom aktual, yang mencakup beberapa informasi tambahan seperti array null untuk kolom yang dapat diubah ke null dan array offset untuk jenis data dengan panjang variabel.

Gambar berikut mengilustrasikan struktur baris untuk tabel yang memiliki dua indeks:

Struktur baris untuk tabel yang memiliki dua indeks.

Tanda waktu awal dan akhir menunjukkan periode di mana versi baris tertentu valid. Transaksi yang dimulai dalam interval ini dapat melihat versi baris ini. Untuk detail selengkapnya, lihat Transaksi dalam Tabel Memory-Optimized.

Penunjuk indeks menunjuk ke baris berikutnya dalam rantai milik wadah hash. Gambar berikut mengilustrasikan struktur tabel dengan dua kolom (nama, kota), dan dengan dua indeks, satu pada nama kolom, dan satu di kota kolom.

Struktur tabel dengan dua kolom dan indeks.

Dalam angka ini, nama John dan Jane di-hash ke ember pertama. Susan di-hash ke ember kedua. Kota-kota Beijing dan Bogota di-hash ke ember pertama. Paris dan Praha di-hash ke ember kedua.

Dengan demikian, rantai untuk indeks hash pada nama adalah sebagai berikut:

  • Wadah pertama: (Yohanes, Beijing); (John, Paris); (Jane, Praha)

  • Wadah kedua: (Susan, Bogota)

Rantai untuk indeks di kota adalah sebagai berikut:

  • Wadah pertama: (Yohanes, Beijing), (Susan, Bogota)

  • Wadah kedua: (Yohanes, Paris), (Jane, Praha)

Tanda waktu akhir ∞ (tak terbatas) menunjukkan bahwa ini adalah versi baris yang saat ini valid. Baris belum diperbarui atau dihapus sejak versi baris ini ditulis.

Untuk waktu yang lebih besar dari 200, tabel berisi baris berikut:

Nama Kota
John Beijing
Jane Praha

Namun, setiap transaksi aktif dengan waktu mulai 100 akan melihat versi tabel berikut:

Nama Kota
John Paris
Jane Praha
Susan Bogata

Contoh: Komputasi Ukuran Tabel dan Baris

Untuk indeks hash, jumlah wadah aktual dibulatkan ke atas ke daya terdekat 2. Misalnya, jika bucket_count yang ditentukan adalah 100000, jumlah wadah aktual untuk indeks adalah 131072.

Pertimbangkan tabel Pesanan dengan definisi berikut:

CREATE TABLE dbo.Orders (  
     OrderID int NOT NULL   
           PRIMARY KEY NONCLUSTERED,  
     CustomerID int NOT NULL   
           INDEX IX_CustomerID HASH WITH (BUCKET_COUNT=10000),  
     OrderDate datetime NOT NULL,  
     OrderDescription nvarchar(1000)  
) WITH (MEMORY_OPTIMIZED=ON)  
GO  

Perhatikan bahwa tabel ini memiliki satu indeks hash dan indeks non-kluster (kunci primer). Ini juga memiliki tiga kolom panjang tetap dan satu kolom dengan panjang variabel, dengan salah satu kolomnya adalah NULLable (OrderDescription). Mari kita asumsikan tabel Pesanan memiliki 8379 baris, dan panjang rata-rata nilai dalam kolom OrderDescription adalah 78 karakter.

Untuk menentukan ukuran tabel, pertama-tama tentukan ukuran indeks. bucket_count untuk kedua indeks ditentukan sebagai 10000. Ini dibulatkan ke atas ke daya terdekat 2: 16384. Oleh karena itu, ukuran total indeks untuk tabel Pesanan adalah:

8 * 16384 = 131072 bytes  

Yang tersisa adalah ukuran data tabel, yaitu,

[row size] * [row count] = [row size] * 8379  

(Tabel contoh memiliki 8379 baris.) Sekarang, kita memiliki:

[row size] = [row header size] + [actual row body size]  
[row header size] = 24 + 8 * [number of indices] = 24 + 8 * 1 = 32 bytes  

Selanjutnya, mari kita hitung [ukuran isi baris aktual]:

  • Kolom jenis dangkal:

    SUM([size of shallow types]) = 4 [int] + 4 [int] + 8 [datetime] = 16  
    
  • Padding kolom dangkal adalah 0, karena ukuran kolom dangkal total genap.

  • Array offset untuk kolom tipe dalam:

    2 + 2 * [number of deep type columns] = 2 + 2 * 1 = 4  
    
  • Array NULL = 1

  • Padding array NULL = 1, karena ukuran array NULL ganjil dan ada kolom jenis dalam.

  • Padding

    • 8 adalah persyaratan penyelarasan terbesar.

    • Ukuran sejauh ini adalah 16 + 0 + 4 + 1 + 1 = 22.

    • Kelipatan terdekat dari 8 adalah 24.

    • Total padding adalah 24 - 22 = 2 byte.

  • Tidak ada kolom tipe dalam panjang tetap (kolom jenis dalam panjang tetap: 0.).

  • Ukuran sebenarnya dari kolom tipe dalam adalah 2 * 78 = 156. Kolom jenis dalam tunggal OrderDescription memiliki jenis nvarchar.

[actual row body size] = 24 + 156 = 180 bytes  

Untuk menyelesaikan penghitungan:

[row size] = 32 + 180 = 212 bytes  
[table size] = 8 * 16384 + 212 * 8379 = 131072 + 1776348 = 1907420  

Total ukuran tabel dalam memori dengan demikian sekitar 2 megabyte. Ini tidak memperhitungkan potensi overhead yang dikeluarkan oleh alokasi memori serta penerapan versi baris apa pun yang diperlukan untuk transaksi yang mengakses tabel ini.

Memori aktual yang dialokasikan untuk dan digunakan oleh tabel ini dan indeksnya dapat diperoleh melalui kueri berikut:

select * from sys.dm_db_xtp_table_memory_stats  
where object_id = object_id('dbo.Orders')  

Lihat juga

Tabel yang Dioptimalkan Memori