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 OLTP Dalam Memori.

Sampel memigrasikan lima tabel dalam database ke memori yang dioptimalkan AdventureWorks2022 , dan mencakup beban kerja demo untuk pemrosesan 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 tradeoff yang dibuat dalam memigrasikan tabel ke OLTP Dalam Memori untuk memperhitungkan fitur yang belum (belum) didukung untuk tabel yang dioptimalkan 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 untuk instruksi 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 dioptimalkan memori membawa 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 header tentang pesanan penjualan. Setiap pesanan penjualan memiliki satu baris dalam tabel ini.

Sales.SalesOrderDetail_inmem

  • Detail pesanan penjualan. Setiap item baris pesanan penjualan memiliki 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 daftar mereka.

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 beban kerja pemrosesan pesanan throughput tinggi dengan banyak konkurensi, sumber daya global apa pun dapat menjadi titik ketidakcocokan. Waktu sistem adalah sumber daya global seperti itu, dan kami telah mengamati bahwa itu dapat menjadi hambatan saat menjalankan beban kerja OLTP Dalam Memori yang menyisipkan pesanan penjualan, khususnya jika waktu sistem perlu diambil untuk beberapa kolom di header pesanan penjualan, serta detail pesanan penjualan. Masalah ditangani dalam sampel ini dengan mengambil waktu sistem hanya sekali untuk setiap pesanan penjualan yang dimasukkan, dan menggunakan nilai tersebut untuk kolom tanggalwaktu di SalesOrderHeader_inmem dan SalesOrderDetail_inmem, dalam prosedur Sales.usp_InsertSalesOrder_inmemtersimpan .

  • Jenis data yang ditentukan pengguna alias (UDT) - Tabel asli menggunakan dua UDT dbo.OrderNumber alias 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 dapat diubah ke null dalam kunci indeks - Dalam tabel asli, kolom SalesPersonID dapat diubah ke null, sementara dalam tabel baru kolom tidak dapat diubah ke 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.

Sales.SalesOrderDetail

  • Batasan default - mirip SalesOrderHeaderdengan , batasan default yang memerlukan tanggal/waktu sistem tidak dimigrasikan, sebaliknya prosedur tersimpan yang menyisipkan pesanan penjualan mengurus 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.

Production.Product

  • UDT alias - tabel asli menggunakan jenis dbo.Flagdata yang ditentukan pengguna , 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.

Sales.SpecialOffer

  • 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 titik dan sisipan baris. Namun, seseorang harus mempertimbangkan bahwa mereka tidak mendukung pemindaian rentang, pemindaian yang diurutkan, atau pencarian pada kolom kunci indeks terkemuka. Oleh karena itu, perawatan 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, yang semuanya merupakan indeks HASH karena alasan performa, dan karena tidak ada pemindaian yang diurutkan atau rentang yang diperlukan untuk beban kerja.

  • 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 karena alasan performa, dan karena tidak ada pemindaian yang diurutkan atau rentang yang diperlukan untuk beban kerja.

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

  • Indeks HASH pada (SalesOrderID): pencarian berdasarkan pesanan penjualan sering: Anda akan ingin menemukan semua item baris 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 berada ProductID di jalur penting untuk beban kerja demo, oleh karena itu ini adalah indeks hash

  • Indeks NONCLUSTERED pada (Name): ini akan memungkinkan pemindaian nama produk yang diurutkan

  • 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. Ini bucket_count berukuran 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 pemanfaatan Memori Bagian 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 dalam database dan menghasilkan untuk pesanan penjualan tersebut SalesOrderID . Sebagai parameter input, dibutuhkan detail untuk header pesanan penjualan, serta item baris dalam pesanan.

    • Parameter output:

      • @SalesOrderID int - SalesOrderID untuk pesanan penjualan yang baru saja dimasukkan
    • Parameter input (diperlukan):

      • @DueDate datetime2

      • @CustomerID Int

      • @BillToAddressID [int]

      • @ShipToAddressID [int]

      • @ShipMethodID [int]

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

    • Parameter input (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 berarti dipanggil dari prosedur Sales.usp_UpdateSalesOrderShipInfo_inmemtersimpan pembungkus . Jika klien dapat menangani kegagalan dan menerapkan logika coba lagi, Anda dapat memanggil prosedur ini secara langsung, daripada menggunakan prosedur tersimpan pembungkus.

Prosedur tersimpan berikut digunakan untuk beban kerja demo.

  • Demo.usp_DemoReset

    • Mengatur ulang demo dengan mengosongkan dan menyetel SalesOrderHeader ulang tabel 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 eksekusi selesai untuk semua utas, ostress akan melaporkan waktu yang diperlukan untuk semua utas 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 prompt 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 prompt perintah terletak di folder penginstalan Utilitas RML.

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

  • -S nama instans Microsoft SQL Server untuk disambungkan

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

  • -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 di bawah ini membuat parameter bernilai tabel (TVP) dengan data sampel, dan memanggil prosedur untuk menyisipkan pesanan penjualan dengan lima item baris.

Alat ostress digunakan untuk menjalankan panggilan prosedur tersimpan secara paralel, untuk mensimulasikan klien yang menyisipkan pesanan penjualan secara bersamaan.

Reset demo setelah setiap stres menjalankan eksekusi 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 dilakukan secara wajar pada server sederhana (misalnya, 8 fisik, 16 inti logis), dan penyimpanan SSD dasar untuk 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 diturunkan skalanya dengan menyisipkan 1 juta pesanan penjualan, lihat instruksi di 'In-Memory OLTP\readme.txt' yang merupakan bagian dari arsip SQLServer2016Samples.zip.

Tabel yang dioptimalkan 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 tidak demikian, 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 ketidakcocokan kait: transaksi bersamaan mencoba menulis ke halaman data yang sama; kait digunakan untuk memastikan hanya satu transaksi pada satu waktu yang dapat menulis ke halaman. Mesin OLTP Dalam Memori bebas kait, dan baris data tidak diatur dalam halaman. Dengan demikian, transaksi bersamaan tidak memblokir sisipan satu sama lain, sehingga memungkinkan SQL Server untuk sepenuhnya menggunakan CPU.

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 melayang di sekitar 24%.

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

Mereset 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 sisipan, setiap eksekusi akan mengonsumsi lebih banyak memori, dan dengan demikian diperlukan reset untuk mencegah kehabisan memori. Jumlah memori yang digunakan setelah eksekusi dibahas dalam pemanfaatan Memori Bagian 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, perolehan performa dengan OLTP Dalam Memori kemungkinan akan kurang dari 2X. Ketidakcocokan kait hanya masalah yang signifikan jika ada tingkat konkurensi yang tinggi.

  • Jumlah inti rendah yang tersedia untuk SQL Server: Ini berarti akan ada tingkat konkurensi rendah dalam sistem, karena hanya ada sebanyak mungkin transaksi yang dijalankan secara bersamaan karena ada 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 tersempitan pada IO log. Meskipun pengelogan lebih efisien dengan OLTP Dalam Memori, jika IO log adalah hambatan, potensi perolehan performa terbatas.

    • Gejala: jika pemanfaatan CPU tidak mendekati 100% atau sangat lonjakan saat menjalankan beban kerja pada tabel yang dioptimalkan memori, ada kemungkinan ada hambatan IO 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 logis.

Pemanfaatan memori untuk tabel yang dioptimalkan memori

Pemanfaatan database secara keseluruhan

Kueri berikut dapat digunakan untuk mendapatkan total pemanfaatan memori untuk OLTP Dalam Memori 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 pages_MB
MEMORYCLERK_XTP Default 94
MEMORYCLERK_XTP DB_ID_5 877
MEMORYCLERK_XTP Default 0
MEMORYCLERK_XTP Default 0

Petugas memori default berisi struktur memori di seluruh sistem dan relatif kecil. Petugas memori untuk database pengguna, dalam hal ini database dengan ID 5 ( database_id mungkin berbeda dalam instans Anda), adalah 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 memory_allocated_for_table_kb memory_allocated_for_indexes_kb
SpecialOfferProduct_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 menyisipkan 10 juta pesanan penjualan, pemanfaatan memori all-up terlihat mirip 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 Default 0
MEMORYCLERK_XTP Default 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 memory_allocated_for_table_kb memory_allocated_for_indexes_kb
SalesOrderDetail_inmem 5113761 663552
DemoSalesOrderDetailSeed 64 10368
SpecialOffer_inmem 2 8192
SalesOrderHeader_inmem 1575679 147456
Product_inmem 111 12032
SpecialOfferProduct_inmem 64 3712
DemoSalesOrderHeaderSeed 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 reset demo

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 Default 2261
MEMORYCLERK_XTP DB_ID_5 7396
MEMORYCLERK_XTP Default 0
MEMORYCLERK_XTP Default 0

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

Jika Anda memulai eksekusi kedua beban kerja demo, Anda akan melihat pemanfaatan memori berkurang pada awalnya, 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 Default 1863
MEMORYCLERK_XTP DB_ID_5 7390
MEMORYCLERK_XTP Default 0
MEMORYCLERK_XTP Default 0

Pemanfaatan disk untuk tabel yang dioptimalkan 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.

Melihat lebih dekat dari 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 file_type_desc 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 satu pasang file (data, delta) per prosesor logis. Selain itu, file data telah diukur sebelumnya pada 128 MB, dan file delta pada 8 MB, untuk membuat penyisipan 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 eksekusi pengujian yang menyisipkan 10 juta pesanan penjualan, ukuran on-disk keseluruhan 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;
state_desc file_type_desc 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

Kami masih memiliki 16 pasang file yang telah dibuat sebelumnya, siap untuk pergi karena titik pemeriksaan ditutup.

Ada satu pasangan yang sedang dibangun, yang digunakan sampai titik 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 reset demo

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 dipindahkan melalui berbagai tahap mereka dan akhirnya dibuang, sejumlah titik pemeriksaan dan peristiwa pemotongan log perlu terjadi, untuk memulai penggabungan file titik pemeriksaan, serta untuk memulai pengumpulan 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 file_type_desc jumlah ukuran pada disk MB
DIBUAT SEBELUMNYA DATA 16 2048
DIBUAT SEBELUMNYA DELTA 16 128
AKTIF DATA 38 5152
AKTIF DELTA 38 1331
GABUNGKAN TARGET DATA 7 896
GABUNGKAN TARGET 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 titik pemeriksaan melewati berbagai tahap.

Setelah eksekusi kedua dari beban kerja masukkan 10 juta pesanan penjualan, Anda akan melihat pemanfaatan disk sangat mirip dengan, meskipun belum tentu sama seperti setelah eksekusi 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 file_type_desc 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 utas bersamaan memerlukan pasangan file baru pada saat yang sama, dan dengan demikian memindahkan pasangan dari 'dibuat sebelumnya' ke 'dalam konstruksi'.

Langkah berikutnya