Bagikan melalui


Database Sampel untuk OLTP Dalam Memori

Berlaku untuk: SQL ServerAzure SQL Database

Gambaran Umum

Sampel ini menampilkan fitur OLTP Dalam Memori. Ini menunjukkan tabel yang dioptimalkan memori dan prosedur tersimpan yang dikompilasi secara asli, dan dapat digunakan untuk menunjukkan manfaat performa OLTP Dalam Memori.

Catatan

Untuk melihat topik ini untuk SQL Server 2014 (12.x), lihat Ekstensi ke AdventureWorks untuk Menunjukkan In-Memory OLTP.

Sampel ini memigrasikan lima tabel dalam database AdventureWorks2022 ke memori yang dioptimalkan, serta mencakup beban kerja demo untuk pengolahan pesanan penjualan. Anda dapat menggunakan beban kerja demo ini untuk melihat manfaat performa menggunakan OLTP Dalam Memori di server Anda.

Dalam deskripsi sampel, kita membahas kompromi yang dilakukan dalam memigrasikan tabel ke OLTP Dalam Memori untuk memperhitungkan fitur-fitur yang saat ini belum didukung pada tabel yang dioptimalkan untuk memori.

Dokumentasi sampel ini disusun sebagai berikut:

Prasyarat

  • SQL Server 2016 (13.x)

  • Untuk pengujian performa, server dengan spesifikasi yang mirip dengan lingkungan produksi Anda. Untuk sampel khusus ini, Anda harus memiliki setidaknya 16 GB memori yang tersedia untuk SQL Server. Untuk panduan umum tentang perangkat keras untuk OLTP Dalam Memori, lihat posting blog berikut: Pertimbangan perangkat keras untuk OLTP Dalam Memori di SQL Server 2014

Menginstal sampel OLTP Dalam Memori berdasarkan AdventureWorks

Ikuti langkah-langkah berikut untuk menginstal sampel:

  1. Unduh AdventureWorks2016_EXT.bak dan SQLServer2016Samples.zip dari: https://github.com/microsoft/sql-server-samples/releases/tag/adventureworks ke folder lokal, misalnya C:\Temp.

  2. Pulihkan cadangan database menggunakan Transact-SQL atau SQL Server Management Studio:

    1. Identifikasi folder target dan nama file untuk file data, misalnya

      'h:\DATA\AdventureWorks2022_Data.mdf'

    2. Identifikasi folder target dan nama file untuk file log, misalnya

      'i:\DATA\AdventureWorks2022_log.ldf'

      1. File log harus ditempatkan pada drive yang berbeda dari file data, idealnya drive latensi rendah seperti penyimpanan SSD atau PCIe, untuk performa maksimum.

    Contoh skrip T-SQL:

    RESTORE DATABASE [AdventureWorks2022]   
      FROM DISK = N'C:\temp\AdventureWorks2022.bak'   
        WITH FILE = 1,    
      MOVE N'AdventureWorks2022_Data' TO N'h:\DATA\AdventureWorks2022_Data.mdf',    
      MOVE N'AdventureWorks2022_Log' TO N'i:\DATA\AdventureWorks2022_log.ldf',  
      MOVE N'AdventureWorks2022_mod' TO N'h:\data\AdventureWorks2022_mod'  
     GO  
    
  3. Untuk melihat contoh skrip dan beban kerja, bongkar file SQLServer2016Samples.zip ke folder lokal. Lihat file OLTP\readme.txt dalam memori untuk petunjuk tentang menjalankan beban kerja.

Deskripsi tabel dan prosedur sampel

Sampel membuat tabel baru untuk produk dan pesanan penjualan, berdasarkan tabel yang ada di AdventureWorks2022. Skema tabel baru mirip dengan tabel yang ada, dengan beberapa perbedaan, seperti yang dijelaskan di bawah ini.

Tabel baru yang telah dioptimalkan untuk memori memiliki akhiran '_inmem'. Sampel ini juga mencakup tabel terkait yang membawa akhiran '_ondisk' - tabel ini dapat digunakan untuk membuat perbandingan satu-ke-satu antara performa tabel yang dioptimalkan memori dan tabel berbasis disk pada sistem Anda.

Tabel yang dioptimalkan memori yang digunakan dalam beban kerja untuk perbandingan performa sepenuhnya tahan lama dan sepenuhnya dicatat. Mereka tidak mengorbankan durabilitas atau keandalan untuk mencapai perolehan performa.

Beban kerja target untuk sampel ini adalah pemrosesan pesanan penjualan, di mana kami mempertimbangkan juga informasi tentang produk dan diskon. Untuk akhir ini, kita menggunakan tabel SalesOrderHeader, , SalesOrderDetail, ProductSpecialOffer, dan SpecialOfferProduct.

Dua prosedur tersimpan baru, Sales.usp_InsertSalesOrder_inmem dan Sales.usp_UpdateSalesOrderShipInfo_inmem, digunakan untuk menyisipkan pesanan penjualan dan untuk memperbarui informasi pengiriman pesanan penjualan tertentu.

Skema Demo baru berisi tabel pembantu dan prosedur tersimpan untuk menjalankan beban kerja demo.

Secara konkret, sampel OLTP Dalam Memori menambahkan objek berikut ke AdventureWorks2022:

Tabel ditambahkan oleh sampel

Tabel baru

Sales.SalesOrderHeader_inmem

  • Informasi utama tentang pesanan penjualan. Setiap pesanan penjualan memiliki satu baris dalam tabel ini.

Sales.SalesOrderDetail_inmem

  • Detail pesanan penjualan. Setiap item pesanan penjualan ditampilkan dalam satu baris dalam tabel ini.

Sales.SpecialOffer_inmem

  • Informasi tentang penawaran khusus, termasuk persentase diskon yang terkait dengan setiap penawaran khusus.

Sales.SpecialOfferProduct_inmem

  • Tabel referensi antara penawaran khusus dan produk. Setiap penawaran khusus dapat menampilkan nol atau lebih produk, dan setiap produk dapat ditampilkan dalam nol atau lebih penawaran khusus.

Production.Product_inmem

  • Informasi tentang produk, termasuk harga eceran.

Demo.DemoSalesOrderDetailSeed

  • Digunakan dalam beban kerja demo untuk membuat pesanan penjualan sampel.

Variasi tabel berbasis disk:

  • Sales.SalesOrderHeader_ondisk

  • Sales.SalesOrderDetail_ondisk

  • Sales.SpecialOffer_ondisk

  • Sales.SpecialOfferProduct_ondisk

  • Production.Product_ondisk

Perbedaan antara tabel berbasis disk asli dan yang dioptimalkan memori baru

Sebagian besar, tabel baru yang diperkenalkan oleh sampel ini menggunakan kolom yang sama dan jenis data yang sama dengan tabel asli. Namun, ada beberapa perbedaan. Kami mencantumkan perbedaan di bawah ini, bersama dengan alasan untuk perubahan.

Sales.SalesOrderHeader_inmem

  • Batasan default didukung untuk tabel yang dioptimalkan memori, dan sebagian besar batasan default yang kami migrasikan apa adanya. Namun, tabel Sales.SalesOrderHeader asli berisi dua batasan default yang mengambil tanggal saat ini, untuk kolom OrderDate dan ModifiedDate. Dalam pemrosesan pesanan dengan throughput tinggi dan tingkat konkurensi yang tinggi, sumber daya global apa pun dapat menjadi titik perebutan. Waktu sistem merupakan sumber daya global yang penting, dan kami telah mengamati bahwa itu dapat menjadi kendala saat menjalankan beban kerja OLTP Dalam Memori yang menyisipkan pesanan penjualan, terutama jika waktu sistem perlu diambil untuk beberapa kolom di header pesanan penjualan dan juga detail pesanan penjualan. Masalah ditangani dalam sampel ini dengan mengambil waktu sistem sekali saja setiap kali pesanan penjualan dimasukkan, serta menggunakan nilai itu untuk kolom tanggal waktu di SalesOrderHeader_inmem dan SalesOrderDetail_inmem, dalam prosedur tersimpan Sales.usp_InsertSalesOrder_inmem.

  • Alias jenis data yang ditentukan pengguna (UDT) - Tabel asli menggunakan dua alias UDT dbo.OrderNumber dan dbo.AccountNumber, untuk kolom PurchaseOrderNumber dan AccountNumber, masing-masing. SQL Server 2016 (13.x) tidak mendukung alias UDT untuk tabel yang dioptimalkan memori, sehingga tabel baru menggunakan jenis data sistem nvarchar(25) dan nvarchar(15), masing-masing.

  • Kolom yang bisa bernilai null dalam kunci indeks - Dalam tabel asli, kolom SalesPersonID bisa bernilai null, sementara dalam tabel baru kolom tersebut tidak bisa bernilai null dan memiliki batasan default dengan nilai (-1). Keadaan ini karena indeks pada tabel yang dioptimalkan memori tidak dapat memiliki kolom null di kunci indeks; -1 adalah pengganti null dalam hal ini.

  • Kolom komputasi - Kolom SalesOrderNumber komputasi dan TotalDue dihilangkan, karena SQL Server 2016 (13.x) tidak mendukung kolom komputasi dalam tabel yang dioptimalkan memori. Tampilan Sales.vSalesOrderHeader_extended_inmem baru mencerminkan kolom SalesOrderNumber dan TotalDue. Oleh karena itu, Anda dapat menggunakan tampilan ini jika kolom ini diperlukan.

    • Berlaku untuk: SQL Server 2017 (14.x) CTP 1.1.
      Dimulai dengan SQL Server 2017 (14.x) CTP 1.1, kolom komputasi didukung dalam tabel dan indeks yang dioptimalkan memori.
  • Batasan kunci asing didukung untuk tabel yang dioptimalkan memori di SQL Server 2016 (13.x), tetapi hanya jika tabel yang dirujuk juga dioptimalkan memori. Kunci asing yang mereferensikan tabel yang juga dimigrasikan ke memori yang dioptimalkan disimpan dalam tabel yang dimigrasikan, sementara kunci asing lainnya dihilangkan. Selain itu, SalesOrderHeader_inmem adalah tabel panas dalam contoh beban kerja, dan batasan kunci asing memerlukan pemrosesan tambahan untuk semua operasi DML, karena memerlukan pencarian di semua tabel lain yang dirujuk dalam batasan ini. Oleh karena itu, asumsinya adalah bahwa aplikasi memastikan integritas referensial untuk Sales.SalesOrderHeader_inmem tabel, dan integritas referensial tidak divalidasi saat baris dimasukkan.

  • Rowguid - Kolom rowguid dihilangkan. Meskipun uniqueidentifier didukung untuk tabel yang dioptimalkan memori, opsi ROWGUIDCOL tidak didukung di SQL Server 2016 (13.x). Kolom semacam ini biasanya digunakan untuk menggabungkan replikasi atau tabel yang memiliki kolom aliran file. Sampel ini tidak mencakup keduanya.

Penjualan.DetailPesananPenjualan

  • Keterbatasan default - mirip dengan SalesOrderHeader, keterbatasan default yang memerlukan tanggal/waktu sistem tidak dimigrasikan, melainkan prosedur tersimpan untuk menyisipkan pesanan penjualan bertanggung jawab memasukkan tanggal/waktu sistem saat ini pada sisipan pertama.

  • Kolom komputasi - kolom LineTotal komputasi tidak dimigrasikan karena kolom komputasi tidak didukung dengan tabel yang dioptimalkan memori di SQL Server 2016 (13.x). Untuk mengakses kolom ini, gunakan tampilan Sales.vSalesOrderDetail_extended_inmem.

  • Rowguid - Kolom rowguid dihilangkan. Untuk detailnya, lihat deskripsi untuk tabel SalesOrderHeader.

Produksi.Produk

  • Alias UDT - tabel asli menggunakan jenis data yang ditentukan pengguna dbo.Flag, yang setara dengan jenis data sistem bit. Tabel yang dimigrasikan menggunakan jenis data bit sebagai gantinya.

  • Rowguid - Kolom rowguid dihilangkan. Untuk detailnya, lihat deskripsi untuk tabel SalesOrderHeader.

Penjualan.PenawaranKhusus

  • Rowguid - Kolom rowguid dihilangkan. Untuk detailnya, lihat deskripsi untuk tabel SalesOrderHeader.

Sales.SpecialOfferProduct

  • Rowguid - Kolom rowguid dihilangkan. Untuk detailnya, lihat deskripsi untuk tabel SalesOrderHeader.

Pertimbangan untuk indeks pada tabel yang dioptimalkan memori

Indeks garis besar untuk tabel yang dioptimalkan memori adalah indeks NONCLUSTERED, yang mendukung pencarian titik (pencarian indeks pada predikat kesetaraan), pemindaian rentang (pencarian indeks dalam predikat ketidaksetaraan), pemindaian indeks penuh, dan pemindaian yang diurutkan. Selain itu, indeks NONCLUSTERED mendukung pencarian pada kolom utama kunci indeks. Bahkan indeks NONCLUSTERED yang dioptimalkan memori mendukung semua operasi yang didukung oleh indeks NONCLUSTERED berbasis disk, dengan satu-satunya pengecualian adalah pemindaian mundur. Oleh karena itu, menggunakan indeks NONCLUSTERED adalah pilihan yang aman untuk indeks Anda.

Indeks HASH dapat digunakan untuk mengoptimalkan beban kerja lebih lanjut. Mereka dioptimalkan untuk pencarian data spesifik dan penyisipan baris. Namun, seseorang harus mempertimbangkan bahwa mereka tidak mendukung pemindaian rentang, pemindaian yang diurutkan, atau pencarian pada kolom kunci indeks terkemuka. Oleh karena itu, kehati-hatian perlu dilakukan saat menggunakan indeks ini. Selain itu, perlu untuk menentukan bucket_count pada waktu pembuatan. Biasanya harus diatur di antara satu dan dua kali jumlah nilai kunci indeks, tetapi menilai berlebihan biasanya bukan masalah.

Untuk informasi selengkapnya:

Indeks pada tabel yang dimigrasikan telah disetel untuk beban kerja pemrosesan pesanan penjualan demo. Beban kerja bergantung pada sisipan dan pencarian titik dalam tabel Sales.SalesOrderHeader_inmem dan Sales.SalesOrderDetail_inmem, dan juga bergantung pada pencarian titik pada kolom kunci utama dalam tabel Production.Product_inmem dan Sales.SpecialOffer_inmem.

Sales.SalesOrderHeader_inmem memiliki tiga indeks, semuanya merupakan indeks HASH untuk alasan kinerja, dan karena tidak diperlukan pemindaian terurut atau berbasis rentang untuk beban kerja ini.

  • Indeks HASH pada (SalesOrderID): bucket_count berukuran 10 juta (dibulatkan hingga 16 juta), karena jumlah pesanan penjualan yang diharapkan adalah 10 juta

  • Indeks HASH pada (SalesPersonID): bucket_count adalah 1 juta. Himpunan data yang disediakan tidak memiliki banyak orang penjualan. Tetapi bucket_count besar ini memungkinkan pertumbuhan di masa depan. Selain itu, Anda tidak membayar penalti performa untuk pencarian titik jika bucket_count terlalu besar.

  • Indeks HASH pada (CustomerID): bucket_count adalah 1 juta. Himpunan data yang disediakan tidak memiliki banyak pelanggan, tetapi ini memungkinkan pertumbuhan di masa depan.

Sales.SalesOrderDetail_inmem memiliki tiga indeks, yang semuanya merupakan indeks HASH demi meningkatkan performa, dan karena tidak memerlukan pemindaian berurutan atau jangkauan untuk beban kerja.

  • Indeks HASH pada (SalesOrderID, SalesOrderDetailID): ini adalah indeks kunci utama, dan meskipun pencarian pada (SalesOrderID, SalesOrderDetailID) jarang, menggunakan indeks HASH pada kunci mempercepat sisipan baris. bucket_count berukuran 50 juta (dibulatkan ke atas menjadi 67 juta): jumlah pesanan penjualan yang diharapkan adalah 10 juta, dan dirancang untuk memiliki rata-rata lima barang per pesanan

  • Indeks HASH pada (SalesOrderID): pencarian berdasarkan pesanan penjualan sering dilakukan: Anda ingin menemukan semua item yang sesuai dengan satu pesanan. bucket_count berukuran 10 juta (dibulatkan hingga 16 juta), karena jumlah pesanan penjualan yang diharapkan adalah 10 juta

  • Indeks HASH pada (ProductID): bucket_count adalah 1 juta. Himpunan data yang disediakan tidak memiliki banyak produk, tetapi ini memungkinkan pertumbuhan di masa mendatang.

Production.Product_inmem memiliki tiga indeks

  • Indeks HASH pada (ProductID): pencarian pada ProductID berada di jalur kritis untuk beban kerja demo, sehingga ini adalah indeks hash.

  • Indeks NONCLUSTERED pada (Name): ini akan memungkinkan pemindaian terurut dari nama produk

  • Indeks NONCLUSTERED pada (ProductNumber): ini akan memungkinkan pemindaian nomor produk yang diurutkan

Sales.SpecialOffer_inmem memiliki satu indeks HASH pada (SpecialOfferID): pencarian titik penawaran khusus berada di bagian penting dari beban kerja demo. bucket_count memiliki ukuran 1 juta untuk memungkinkan pertumbuhan di masa depan.

Sales.SpecialOfferProduct_inmem tidak direferensikan dalam beban kerja demo, dan dengan demikian tidak ada kebutuhan yang jelas untuk menggunakan indeks hash pada tabel ini untuk mengoptimalkan beban kerja - indeks pada (SpecialOfferID, ProductID) dan (ProductID) adalah NONCLUSTERED.

Perhatikan bahwa dalam beberapa jumlah wadah di atas terlalu besar, tetapi tidak jumlah wadah untuk indeks SalesOrderHeader_inmem dan SalesOrderDetail_inmem: mereka berukuran hanya untuk 10 juta pesanan penjualan. Ini dilakukan untuk memungkinkan penginstalan sampel pada sistem dengan ketersediaan memori rendah, meskipun dalam kasus tersebut beban kerja demo akan gagal dengan kehabisan memori. Jika Anda ingin menskalakan jauh lebih dari 10 juta pesanan penjualan, jangan ragu untuk meningkatkan jumlah wadah yang sesuai.

Pertimbangan untuk pemanfaatan memori

Pemanfaatan memori dalam database sampel, baik sebelum dan sesudah menjalankan beban kerja demo, dibahas dalam Bagian Pemanfaatan Memori untuk tabel yang dioptimalkan memori.

Prosedur Tersimpan ditambahkan oleh sampel

Dua prosedur tersimpan utama untuk menyisipkan pesanan penjualan dan memperbarui detail pengiriman adalah sebagai berikut:

  • Sales.usp_InsertSalesOrder_inmem

    • Menyisipkan pesanan penjualan baru ke dalam database dan menghasilkan keluaran SalesOrderID untuk pesanan penjualan tersebut. Sebagai parameter input, dibutuhkan detail untuk header pesanan penjualan, serta item baris dalam pesanan.

    • Parameter keluaran

      • @SalesOrderID int - SalesOrderID untuk pesanan penjualan yang baru saja dimasukkan
    • Parameter masukan yang diperlukan:

      • @DueDate datetime2

      • @CustomerID Int

      • @BillToAddressID [int]

      • @ShipToAddressID [int]

      • @ShipMethodID [int]

      • @SalesOrderDetails Sales.SalesOrderDetailType_inmem - parameter bernilai tabel (TVP) yang berisi item baris pesanan

    • Parameter masukan (opsional):

      • @Status [ tinyint ]

      • @OnlineOrderFlag [bit]

      • @PurchaseOrderNumber [nvarchar](25)

      • @AccountNumber [nvarchar](15)

      • @SalesPersonID [int]

      • @TerritoryID [int]

      • @CreditCardID [int]

      • @CreditCardApprovalCode [varchar](15)

      • @CurrencyRateID [int]

      • @Comment nvarchar(128)

  • Sales.usp_UpdateSalesOrderShipInfo_inmem

    • Perbarui informasi pengiriman untuk pesanan penjualan tertentu. Ini juga akan memperbarui informasi pengiriman untuk semua item baris pesanan penjualan.

    • Ini adalah prosedur pembungkus Sales.usp_UpdateSalesOrderShipInfo_native untuk prosedur tersimpan yang dikompilasi secara asli dengan logika coba lagi untuk menangani potensi konflik (tidak terduga) dengan transaksi bersamaan yang memperbarui urutan yang sama. Untuk informasi selengkapnya, lihat logika coba lagi.

  • Sales.usp_UpdateSalesOrderShipInfo_native

    • Ini adalah prosedur tersimpan yang dikompilasi secara asli yang benar-benar memproses pembaruan untuk informasi pengiriman. Ini dimaksudkan untuk dipanggil dari prosedur tersimpan pembungkus Sales.usp_UpdateSalesOrderShipInfo_inmem. Jika klien dapat menangani kegagalan dan menerapkan logika ulang, Anda dapat memanggil prosedur ini secara langsung, daripada menggunakan prosedur pembungkus yang tersimpan.

Prosedur tersimpan berikut ini digunakan untuk beban kerja demo.

  • Demo.usp_DemoReset

    • Mengatur ulang demo dengan mengosongkan dan mengisi ulang tabel SalesOrderHeader dan SalesOrderDetail.

Prosedur tersimpan berikut digunakan untuk menyisipkan dan menghapus dari tabel yang dioptimalkan memori sambil menjamin domain dan integritas referensial.

  • Production.usp_InsertProduct_inmem

  • Production.usp_DeleteProduct_inmem

  • Sales.usp_InsertSpecialOffer_inmem

  • Sales.usp_DeleteSpecialOffer_inmem

  • Sales.usp_InsertSpecialOfferProduct_inmem

Akhirnya prosedur tersimpan berikut digunakan untuk memverifikasi domain dan integritas referensial.

  1. dbo.usp_ValidateIntegrity

    • Parameter opsional: @object_id - ID objek untuk memvalidasi integritas untuk

    • Prosedur ini bergantung pada tabel dbo.DomainIntegrity, , dbo.ReferentialIntegritydan dbo.UniqueIntegrity untuk aturan integritas yang perlu diverifikasi - sampel mengisi tabel ini berdasarkan pemeriksaan, kunci asing, dan batasan unik yang ada untuk tabel asli dalam AdventureWorks2022 database.

    • Ini bergantung pada prosedur dbo.usp_GenerateCKCheckpembantu , , dbo.usp_GenerateFKCheckdan dbo.GenerateUQCheck untuk menghasilkan T-SQL yang diperlukan untuk melakukan pemeriksaan integritas.

Pengukuran Performa menggunakan Beban Kerja Demo

Ostress adalah alat baris perintah yang dikembangkan oleh tim dukungan Microsoft CSS SQL Server. Alat ini dapat digunakan untuk menjalankan kueri atau menjalankan prosedur tersimpan secara paralel. Anda dapat mengonfigurasi jumlah utas untuk menjalankan pernyataan T-SQL tertentu secara paralel, dan Anda dapat menentukan berapa kali pernyataan harus dijalankan pada utas ini; ostress akan memutar utas dan menjalankan pernyataan pada semua utas secara paralel. Setelah semua thread selesai dieksekusi, ostress akan melaporkan waktu yang diperlukan bagi semua thread untuk menyelesaikan eksekusi.

Menginstal ostress

Ostress diinstal sebagai bagian dari Utilitas Report Markup Language (RML) ; tidak ada instalasi mandiri untuk ostress.

Langkah-langkah penginstalan:

  1. Unduh dan jalankan paket penginstalan x64 untuk utilitas RML dari halaman berikut: Unduh RML untuk SQL Server

  2. Jika ada kotak dialog yang mengatakan file tertentu sedang digunakan, pilih 'Lanjutkan'

Menjalankan ostress

Ostress dijalankan dari baris perintah. Paling nyaman untuk menjalankan alat dari "RML Cmd Prompt", yang diinstal sebagai bagian dari Utilitas RML.

Untuk membuka Prompt Cmd RML, ikuti instruksi berikut:

Di Windows, buka menu mulai dengan memilih kunci Windows, dan ketik rml. Pilih "RML Cmd Prompt", yang akan berada dalam daftar hasil pencarian.

Pastikan bahwa command prompt terletak di direktori penginstalan Utilitas RML.

Opsi baris perintah untuk ostress dapat dilihat saat hanya menjalankan ostress.exe tanpa opsi baris perintah apa pun. Opsi utama yang perlu dipertimbangkan untuk menjalankan ostress dengan sampel ini adalah:

  • -S nama instans Microsoft SQL Server untuk dihubungkan

  • -E gunakan Windows authentication untuk menyambungkan (default); jika Anda menggunakan SQL Server authentication, gunakan opsi -U dan -P untuk menentukan nama pengguna dan kata sandi, berturut-turut

  • -d nama database, untuk contoh ini AdventureWorks2022

  • -Q pernyataan T-SQL yang akan dijalankan

  • -n jumlah koneksi yang memproses setiap file/kueri input

  • -adalah jumlah iterasi untuk setiap koneksi untuk menjalankan setiap file/kueri input

Beban Kerja Demo

Prosedur tersimpan utama yang digunakan dalam beban kerja demo adalah Sales.usp_InsertSalesOrder_inmem/ondisk. Skrip berikut ini membuat parameter bernilai tabel (TVP) dengan data sampel dan kemudian memanggil prosedur untuk memasukkan pesanan penjualan dengan lima komponen.

Alat ostress digunakan untuk menjalankan panggilan prosedur tersimpan secara paralel, untuk mempraktikkan pengguna yang memasukkan pesanan penjualan secara bersamaan.

Setel ulang demo setelah setiap kali menjalankan stres Demo.usp_DemoReset. Prosedur ini menghapus baris dalam tabel yang dioptimalkan memori, memotong tabel berbasis disk, dan menjalankan titik pemeriksaan database.

Skrip berikut dijalankan secara bersamaan untuk mensimulasikan beban kerja pemrosesan pesanan penjualan:

DECLARE   
      @i int = 0,   
      @od Sales.SalesOrderDetailType_inmem,   
      @SalesOrderID int,   
      @DueDate datetime2 = sysdatetime(),   
      @CustomerID int = rand() * 8000,   
      @BillToAddressID int = rand() * 10000,   
      @ShipToAddressID int = rand() * 10000,   
      @ShipMethodID int = (rand() * 5) + 1;   
  
INSERT INTO @od   
SELECT OrderQty, ProductID, SpecialOfferID   
FROM Demo.DemoSalesOrderDetailSeed   
WHERE OrderID= cast((rand()*106) + 1 as int);   
  
WHILE (@i < 20)   
BEGIN;   
      EXEC Sales.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od;   
      SET @i += 1   
END

Dengan skrip ini, setiap urutan sampel yang dibangun dimasukkan 20 kali, melalui 20 prosedur tersimpan yang dijalankan dalam perulangan WHILE. Perulangan digunakan untuk memperhitungkan fakta bahwa database digunakan untuk membuat urutan sampel. Di lingkungan produksi yang khas, aplikasi tingkat menengah akan membangun pesanan penjualan yang akan dimasukkan.

Skrip di atas menyisipkan pesanan penjualan ke dalam tabel yang dioptimalkan memori. Skrip untuk memasukkan pesanan penjualan ke dalam tabel berbasis disk diturunkan dengan mengganti dua kemunculan '_inmem' dengan '_ondisk'.

Kami akan menggunakan alat ostress untuk menjalankan skrip menggunakan beberapa koneksi bersamaan. Kami akan menggunakan parameter '-n' untuk mengontrol jumlah koneksi, dan parameter 'r' untuk mengontrol berapa kali skrip dijalankan pada setiap koneksi.

Menjalankan Beban Kerja

Untuk menguji dalam skala besar, kami menyisipkan 10 juta pesanan penjualan, menggunakan 100 koneksi. Pengujian ini berjalan secara wajar pada server sederhana (misalnya, 8 inti fisik, 16 inti logis), dan penyimpanan SSD dasar untuk penyimpanan log. Jika pengujian tidak berkinerja baik pada perangkat keras Anda, lihat Bagian Pemecahan masalah pengujian yang berjalan lambat. Jika Anda ingin mengurangi tingkat stres untuk pengujian ini, turunkan jumlah koneksi dengan mengubah parameter '-n'. Misalnya untuk menurunkan jumlah koneksi menjadi 40, ubah parameter '-n100' menjadi '-n40'.

Sebagai ukuran performa untuk beban kerja, kami menggunakan waktu yang berlalu seperti yang dilaporkan oleh ostress.exe setelah menjalankan beban kerja.

Instruksi dan pengukuran di bawah ini menggunakan beban kerja yang menyisipkan 10 juta pesanan penjualan. Untuk instruksi menjalankan beban kerja yang diskalakan turun yang menyisipkan 1 juta pesanan penjualan, lihat lebih lanjut di 'In-Memory OLTP\readme.txt' yang merupakan bagian dari arsip SQLServer2016Samples.zip.

Tabel yang dioptimalkan untuk memori

Kita akan mulai dengan menjalankan beban kerja pada tabel yang dioptimalkan memori. Perintah berikut membuka 100 utas, masing-masing berjalan untuk 5.000 iterasi. Setiap iterasi menyisipkan 20 pesanan penjualan dalam transaksi terpisah. Ada 20 sisipan per iterasi untuk mengimbangi fakta bahwa database digunakan untuk menghasilkan data yang akan dimasukkan. Hasil ini menghasilkan total 20 * 5.000 * 100 = 10.000.000 sisipan pesanan penjualan.

Buka Prompt Cmd RML, dan jalankan perintah berikut:

Pilih tombol Salin untuk menyalin perintah, dan tempelkan ke prompt perintah Utilitas RML.

ostress.exe -n100 -r5000 -S. -E -dAdventureWorks2022 -q -Q"DECLARE @i int = 0, @od Sales.SalesOrderDetailType_inmem, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand() * 10000, @ShipMethodID int = (rand() * 5) + 1; INSERT INTO @od SELECT OrderQty, ProductID, SpecialOfferID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID= cast((rand()*106) + 1 as int); while (@i < 20) begin; EXEC Sales.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; set @i += 1 end"  

Pada satu server pengujian dengan jumlah total 8 inti fisik (16 logis), ini membutuhkan waktu 2 menit dan 5 detik. Pada server pengujian kedua dengan 24 inti fisik (48 logis), ini membutuhkan waktu 1 menit dan 0 detik.

Amati pemanfaatan CPU saat beban kerja berjalan, misalnya menggunakan task manager. Anda akan melihat bahwa pemanfaatan CPU mendekati 100%. Jika bukan demikian, maka Anda memiliki hambatan IO log, lihat juga Memecahkan masalah pengujian yang berjalan lambat.

Tabel berbasis disk

Perintah berikut akan menjalankan beban kerja pada tabel berbasis disk. Beban kerja ini mungkin memakan waktu cukup lama untuk dijalankan, yang sebagian besar disebabkan oleh ketidakcocokan kait dalam sistem. Tabel yang dioptimalkan memori bebas kait dan dengan demikian tidak menderita masalah ini.

Buka Prompt Cmd RML, dan jalankan perintah berikut:

Pilih tombol Salin untuk menyalin perintah, dan tempelkan ke prompt perintah Utilitas RML.

ostress.exe -n100 -r5000 -S. -E -dAdventureWorks2022 -q -Q"DECLARE @i int = 0, @od Sales.SalesOrderDetailType_ondisk, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand() * 10000, @ShipMethodID int = (rand() * 5) + 1; INSERT INTO @od SELECT OrderQty, ProductID, SpecialOfferID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID= cast((rand()*106) + 1 as int); while (@i < 20) begin; EXEC Sales.usp_InsertSalesOrder_ondisk @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; set @i += 1 end"  

Pada satu server pengujian dengan jumlah total 8 inti fisik (16 logis), ini membutuhkan waktu 41 menit dan 25 detik. Pada server pengujian kedua dengan 24 inti fisik (48 logis), ini membutuhkan waktu 52 menit dan 16 detik.

Faktor utama dalam perbedaan performa antara tabel yang dioptimalkan memori dan tabel berbasis disk dalam pengujian ini adalah fakta bahwa saat menggunakan tabel berbasis disk, SQL Server tidak dapat sepenuhnya menggunakan CPU. Alasannya adalah kekontensian kait: transaksi yang berjalan bersamaan mencoba menulis ke halaman data yang sama; kait digunakan untuk memastikan bahwa hanya satu transaksi yang dapat menulis ke halaman pada satu waktu. Mesin OLTP Dalam Memori bebas kait, dan baris data tidak diatur dalam halaman. Dengan demikian, transaksi bersamaan tidak memblokir sisipan dari transaksi lain, sehingga memungkinkan SQL Server untuk menggunakan CPU secara optimal.

Anda dapat mengamati pemanfaatan CPU saat beban kerja berjalan, misalnya menggunakan task manager. Anda akan melihat dengan tabel berbasis disk, pemanfaatan CPU jauh dari 100%. Pada konfigurasi pengujian dengan 16 prosesor logis, pemanfaatan akan berkisar sekitar 24%.

Secara opsional, Anda dapat melihat jumlah tunggu kait per detik menggunakan Monitor Performa dengan penghitung kinerja \SQL Server:Latches\Latch Waits/sec.

Mengatur ulang demo

Untuk mengatur ulang demo, buka Perintah Cmd RML, dan jalankan perintah berikut:

ostress.exe -S. -E -dAdventureWorks2022 -Q"EXEC Demo.usp_DemoReset"  

Bergantung pada perangkat keras, mungkin perlu waktu beberapa menit untuk dijalankan.

Kami merekomendasikan reset setelah setiap demo berjalan. Karena beban kerja ini hanya untuk penyisipan, setiap kali dijalankan akan mengonsumsi lebih banyak memori, oleh karena itu diperlukan pengaturan ulang untuk mencegah kehabisan memori. Jumlah memori yang digunakan setelah pekerjaan dijalankan dibahas dalam Bagian Pemanfaatan Memori setelah menjalankan beban kerja.

Pemecahan masalah pengujian yang berjalan lambat

Hasil pengujian biasanya akan bervariasi menurut perangkat keras, dan juga tingkat konkurensi yang digunakan dalam eksekusi pengujian. Beberapa hal yang perlu dicari jika hasilnya tidak seperti yang diharapkan:

  • Jumlah transaksi bersamaan: Saat menjalankan beban kerja pada satu utas, peningkatan performa dengan OLTP Dalam Memori kemungkinan akan kurang dari dua kali lipat. Ketidakcocokan kait hanya masalah yang signifikan jika ada tingkat konkurensi yang tinggi.

  • Jumlah inti yang tersedia untuk SQL Server sedikit: Ini berarti akan ada tingkat keserentakan yang rendah dalam sistem, karena hanya akan ada sebanyak transaksi yang dapat dijalankan secara bersamaan sesuai dengan jumlah inti yang tersedia untuk SQL.

    • Gejala: jika pemanfaatan CPU tinggi saat menjalankan beban kerja pada tabel berbasis disk, ini berarti tidak ada banyak ketidakcocokan, menunjuk ke kurangnya konkurensi.
  • Kecepatan drive log: Jika drive log tidak dapat mengikuti tingkat throughput transaksi dalam sistem, beban kerja menjadi terkendala pada IO log. Meskipun pencatatan log lebih efisien dengan In-Memory OLTP, jika IO log menjadi hambatan, potensi peningkatan performa menjadi terbatas.

    • Gejala: jika pemanfaatan CPU tidak mendekati 100% atau sangat berfluktuasi saat menjalankan beban kerja pada tabel yang dioptimalkan memori, ada kemungkinan ada hambatan pada input/output log. Ini dapat dikonfirmasi dengan membuka Resource Monitor dan melihat panjang antrean untuk drive log.

Pemanfaatan Ruang Memori dan Disk dalam Sampel

Di bawah ini kami menjelaskan apa yang diharapkan dalam hal pemanfaatan memori dan ruang disk untuk database sampel. Kami juga menunjukkan hasil yang telah kami lihat di server pengujian dengan 16 inti prosesor logis.

Pemanfaatan memori untuk tabel yang dioptimalkan memori

Pemanfaatan database secara keseluruhan

Kueri berikut dapat digunakan untuk mendapatkan total pemanfaatan memori untuk In-Memory OLTP dalam sistem.

SELECT type  
   , name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  

Rekam jepret setelah database baru saja dibuat:

jenis nama halaman_MB
MEMORYCLERK_XTP Bawaan 94
MEMORYCLERK_XTP DB_ID_5 877
MEMORYCLERK_XTP Bawaan 0
MEMORYCLERK_XTP Bawaan 0

Penjaga memori default berisi struktur memori yang berlaku untuk seluruh sistem dan berukuran relatif kecil. Pengelola memori untuk database pengguna, dalam hal ini database dengan ID 5 (database_id mungkin berbeda dalam instansi Anda), berukuran sekitar 900 MB.

Pemanfaatan memori per tabel

Kueri berikut dapat digunakan untuk menelusuri paling detail pemanfaatan memori tabel individual dan indeksnya:

SELECT object_name(t.object_id) AS [Table Name]  
     , memory_allocated_for_table_kb  
 , memory_allocated_for_indexes_kb  
FROM sys.dm_db_xtp_table_memory_stats dms JOIN sys.tables t   
ON dms.object_id=t.object_id  
WHERE t.type='U';  

Tabel berikut ini menampilkan hasil kueri ini untuk penginstalan sampel baru:

Nama Tabel memori_dialokasikan_untuk_tabel_kb memori_dialokasikan_untuk_indeks_kb
ProdukPenawaranKhusus_inmem 64 3840
DemoSalesOrderHeaderSeed 1984 5504
SalesOrderDetail_inmem 15316 663552
DemoSalesOrderDetailSeed 64 10432
SpecialOffer_inmem 3 8192
SalesOrderHeader_inmem 7168 147456
Product_inmem 124 12352

Seperti yang Anda lihat tabelnya cukup kecil: SalesOrderHeader_inmem berukuran sekitar 7 MB, dan SalesOrderDetail_inmem berukuran sekitar 15 MB.

Apa yang mencolok di sini adalah ukuran memori yang dialokasikan untuk indeks, dibandingkan dengan ukuran data tabel. Itu karena indeks hash dalam sampel telah diukur sebelumnya untuk ukuran data yang lebih besar. Perhatikan bahwa indeks hash memiliki ukuran tetap, dan dengan demikian ukurannya tidak akan tumbuh dengan ukuran data dalam tabel.

Pemanfaatan memori setelah menjalankan beban kerja

Setelah memasukkan 10 juta pesanan penjualan, pemanfaatan memori keseluruhan serupa dengan yang berikut ini:

SELECT type  
, name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%'  
jenis nama pages_MB
MEMORYCLERK_XTP Default 146
MEMORYCLERK_XTP DB_ID_5 7374
MEMORYCLERK_XTP Bawaan 0
MEMORYCLERK_XTP Bawaan 0

Seperti yang Anda lihat, SQL Server menggunakan sedikit di bawah 8 GB untuk tabel dan indeks yang dioptimalkan memori dalam database sampel.

Melihat penggunaan memori terperinci per tabel setelah satu contoh dijalankan:

SELECT object_name(t.object_id) AS [Table Name]  
     , memory_allocated_for_table_kb  
 , memory_allocated_for_indexes_kb  
FROM sys.dm_db_xtp_table_memory_stats dms JOIN sys.tables t   
ON dms.object_id=t.object_id  
WHERE t.type='U'  
Nama Tabel memori_dialokasikan_untuk_tabel_kb memori_dialokasikan_untuk_indeks_kb
DetailPesananPenjualan_inmem 5113761 663552
PesananPenjualanDetailDemoSeed 64 10368
PenawaranKhusus_inmem 2 8192
SalesOrderHeader_inmem 1575679 147456
Product_inmem 111 12032
** ProdukPenawaranKhusus_inmem 64 3712
DemoPenjulananOrderHeaderSeed 1984 5504

Kita dapat melihat total sekitar 6,5 GB data. Perhatikan bahwa ukuran indeks pada tabel SalesOrderHeader_inmem dan SalesOrderDetail_inmem sama dengan ukuran indeks sebelum menyisipkan pesanan penjualan. Ukuran indeks tidak berubah karena kedua tabel menggunakan indeks hash, dan indeks hash statis.

Setelah demo diatur ulang

Prosedur Demo.usp_DemoReset tersimpan dapat digunakan untuk mengatur ulang demo. Ini menghapus data dalam tabel SalesOrderHeader_inmem dan SalesOrderDetail_inmem, dan menyemai ulang data dari tabel SalesOrderHeader asli dan SalesOrderDetail.

Sekarang, meskipun baris dalam tabel telah dihapus, ini tidak berarti bahwa memori segera diklaim kembali. SQL Server mengklaim kembali memori dari baris yang dihapus dalam tabel yang dioptimalkan memori di latar belakang, sesuai kebutuhan. Anda akan melihat bahwa segera setelah reset demo, tanpa beban kerja transaksional pada sistem, memori dari baris yang dihapus belum diklaim kembali:

SELECT type  
, name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%';
jenis nama pages_MB
MEMORYCLERK_XTP Bawaan 2261
MEMORYCLERK_XTP DB_ID_5 7396
MEMORYCLERK_XTP Default 0
MEMORYCLERK_XTP Bawaan 0

Ini diharapkan: memori akan diklaim kembali ketika beban kerja transaksi berjalan.

Jika Anda menjalankan kembali beban kerja demo, Anda akan melihat pemanfaatan memori berkurang pada awal, karena baris yang dihapus sebelumnya dibersihkan. Pada titik tertentu ukuran memori akan meningkat lagi, sampai beban kerja selesai. Setelah memasukkan 10 juta baris setelah reset demo, pemanfaatan memori akan sangat mirip dengan pemanfaatan setelah eksekusi pertama. Contohnya:

SELECT type  
, name  
, pages_kb/1024 AS pages_MB   
FROM sys.dm_os_memory_clerks WHERE type LIKE '%xtp%';
jenis nama pages_MB
MEMORYCLERK_XTP Bawaan 1863
MEMORYCLERK_XTP DB_ID_5 7390
MEMORYCLERK_XTP Bawaan 0
MEMORYCLERK_XTP Bawaan 0

Pemanfaatan disk untuk tabel yang dioptimalkan untuk memori

Ukuran on-disk secara keseluruhan untuk file titik pemeriksaan database pada waktu tertentu dapat ditemukan menggunakan kueri:

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';  
  

Status awal

Ketika sampel grup file dan sampel tabel yang dioptimalkan memori dibuat pada awalnya, sejumlah file titik pemeriksaan telah dibuat sebelumnya dan sistem mulai mengisi file - jumlah file titik pemeriksaan yang telah dibuat sebelumnya tergantung pada jumlah prosesor logis dalam sistem. Karena sampel awalnya sangat kecil, file yang telah dibuat sebelumnya sebagian besar akan kosong setelah pembuatan awal.

Kode berikut menunjukkan ukuran awal pada disk untuk sampel pada komputer dengan 16 prosesor logis:

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';  
Ukuran pada disk dalam MB
2312

Seperti yang Anda lihat, ada perbedaan besar antara ukuran pada disk file titik pemeriksaan, yaitu 2,3 GB, dan ukuran data aktual, yang lebih dekat ke 30 MB.

Menelusuri lebih dalam tentang dari mana asal pemanfaatan ruang disk, Anda bisa menggunakan kueri berikut. Ukuran pada disk yang dikembalikan oleh kueri ini adalah perkiraan untuk file dengan status dalam 5 (DIPERLUKAN UNTUK BACKUP/HA), 6 (DALAM TRANSISI KE TOMBSTONE), atau 7 (TOMBSTONE).

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type;

Untuk status awal sampel, hasilnya akan terlihat seperti untuk server dengan 16 prosesor logis:

state_desc deskripsi_tipe_berkas jumlah ukuran pada disk MB
DIBUAT SEBELUMNYA DATA 16 2048
DIBUAT SEBELUMNYA DELTA 16 128
SEDANG DIBANGUN DATA 1 128
SEDANG DIBANGUN DELTA 1 8

Seperti yang Anda lihat, sebagian besar ruang digunakan oleh data dan file delta yang dibuat sebelumnya. SQL Server telah membuat terlebih dahulu sepasang file (data, delta) untuk setiap prosesor logis. Selain itu, ukuran file data sudah ditentukan di awal menjadi 128 MB, dan file delta menjadi 8 MB, untuk membuat memasukkan data ke dalam file-file ini lebih efisien.

Data aktual dalam tabel yang dioptimalkan memori ada dalam satu file data.

Setelah menjalankan beban kerja

Setelah satu kali uji coba yang menyisipkan 10 juta pesanan penjualan, ukuran keseluruhan pada disk terlihat seperti ini (untuk server pengujian 16-core):

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';  
Ukuran pada disk dalam MB
8828

Ukuran pada disk mendekati 9 GB, yang mendekati ukuran dalam memori data.

Melihat lebih dekat ukuran file titik pemeriksaan di berbagai status:

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type;
deskripsi_status deskripsi_jenis_berkas jumlah Ukuran di disk: MB
DIBUAT SEBELUMNYA DATA 16 2048
DIBUAT SEBELUMNYA DELTA 16 128
SEDANG DIBANGUN DATA 1 128
SEDANG DIBANGUN DELTA 1 8

Kami masih memiliki 16 pasang file yang telah dibuat sebelumnya, siap digunakan saat pos pemeriksaan ditutup.

Ada satu pasangan dalam pembangunan, yang digunakan sampai pos pemeriksaan saat ini ditutup. Seiring dengan file titik pemeriksaan aktif, ini memberikan sekitar 6,5 GB pemanfaatan disk untuk 6,5 GB data dalam memori. Ingat bahwa indeks tidak bertahan pada disk, dan dengan demikian ukuran keseluruhan pada disk lebih kecil dari ukuran dalam memori dalam kasus ini.

Setelah demo di-reset

Setelah reset demo, ruang disk tidak segera diklaim kembali jika tidak ada beban kerja transaksional pada sistem, dan tidak ada titik pemeriksaan database. Agar file titik pemeriksaan dapat dipindahkan melalui berbagai tahap dan akhirnya dibuang, sejumlah titik pemeriksaan serta peristiwa pemangkasan log perlu terjadi untuk memulai penggabungan file titik pemeriksaan, serta untuk memulai pengelolaan sampah. Ini akan terjadi secara otomatis jika Anda memiliki beban kerja transaksional dalam sistem (dan mengambil cadangan log reguler, jika Anda menggunakan model pemulihan PENUH), tetapi tidak ketika sistem menganggur, seperti dalam skenario demo.

Dalam contoh, setelah reset demo, Anda mungkin melihat sesuatu seperti:

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';
Ukuran pada disk dalam MB
11839

Pada hampir 12 GB, ini secara signifikan lebih dari 9 GB yang kami miliki sebelum reset demo. Ini karena beberapa penggabungan file titik pemeriksaan telah dimulai, tetapi beberapa target penggabungan belum diinstal, dan beberapa file sumber gabungan belum dibersihkan, seperti yang dapat dilihat dari berikut ini:

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type;
state_desc deskripsi_tipe_berkas menghitung ukuran pada disk MB
DIBUAT SEBELUMNYA DATA 16 2048
DIBUAT SEBELUMNYA DELTA 16 128
AKTIF DATA 38 5152
AKTIF DELTA 38 1331
GABUNGKAN SASARAN DATA 7 896
GABUNGKAN SASARAN DELTA 7 56
SUMBER GABUNGAN data 13 1772
SUMBER GABUNGAN DELTA 13 455

Target penggabungan diinstal dan sumber gabungan dibersihkan saat aktivitas transaksi terjadi dalam sistem.

Setelah menjalankan beban kerja demo kedua, memasukkan 10 juta pesanan penjualan setelah reset demo, Anda akan melihat bahwa file yang dibangun selama eksekusi pertama beban kerja telah dibersihkan. Jika Anda menjalankan kueri di atas beberapa kali saat beban kerja berjalan, Anda dapat melihat file checkpoint berpindah ke berbagai tahap.

Setelah pelaksanaan kedua dari beban kerja memasukkan 10 juta pesanan penjualan, Anda akan melihat penggunaan disk yang sangat mirip, meskipun belum tentu sama seperti setelah pelaksanaan pertama, karena sistem bersifat dinamis. Contohnya:

SELECT state_desc  
 , file_type_desc  
 , COUNT(*) AS [count]  
 , SUM(CASE  
   WHEN state = 5 AND file_type=0 THEN 128*1024*1024  
   WHEN state = 5 AND file_type=1 THEN 8*1024*1024  
   WHEN state IN (6,7) THEN 68*1024*1024  
   ELSE file_size_in_bytes  
    END) / 1024 / 1024 AS [on-disk size MB]   
FROM sys.dm_db_xtp_checkpoint_files  
GROUP BY state, state_desc, file_type, file_type_desc  
ORDER BY state, file_type;
state_desc deskripsi_jenis_berkas jumlah ukuran pada disk MB
DIBUAT SEBELUMNYA DATA 16 2048
DIBUAT SEBELUMNYA DELTA 16 128
SEDANG DIBANGUN DATA 2 268
SEDANG DIBANGUN DELTA 2 16
AKTIF Data 41 5608
AKTIF DELTA 41 328

Dalam hal ini, ada dua pasangan file titik pemeriksaan dalam status 'sedang dibangun', yang berarti beberapa pasangan file dipindahkan ke status 'under construction', kemungkinan karena tingkat konkurensi yang tinggi dalam beban kerja. Beberapa thread bersamaan memerlukan pasangan file baru pada saat yang sama, dan dengan demikian memindahkan pasangan dari 'dibuat sebelumnya' ke 'sedang dibangun'.

Langkah berikutnya