Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:SQL Server
Azure SQL Veritabanı
Genel bakış
Bu örnek, bellek içi OLTP özelliğini gösterir. Bellek için optimize edilmiş tabloları ve yerel derlenmiş saklı yordamları gösterir; bellek içi OLTP'nin performans avantajlarını göstermek için kullanılabilir.
Not
SQL Server 2014 (12.x) için bu makaleyi görüntülemek için bkz. In-Memory OLTP'yi Göstermek için AdventureWorks Uzantıları.
Örnek, AdventureWorks2025 veritabanındaki beş tabloyu bellek için optimize edilmiş hâle getirir ve satış siparişi işleme için tanıtım amaçlı bir iş yükü içerir. Sunucunuzda bellek içi OLTP kullanmanın performans avantajını görmek için bu tanıtım iş yükünü kullanabilirsiniz.
Örnek açıklamasında, hafıza için iyileştirilmiş tablolar için (henüz) desteklenmeyen özellikleri dikkate almak üzere tabloları bellek içi OLTP'ye geçirme sırasında yapılan tercihleri ele alıyoruz.
Bu örneğin belgeleri aşağıdaki gibi yapılandırılmıştır:
Örneği yüklemek ve tanıtım senaryosunu çalıştırmak için önkoşullar.
AdventureWorks tabanlı In-Memory OLTP örneğini yükleme yönergeleri.
Örnek tabloların ve yordamların açıklaması - bellek içi OLTP örneği tarafından eklenen
AdventureWorks2025tablo ve yordamların açıklamalarının yanı sıra bazı özgünAdventureWorks2025tabloları bellek için en iyi duruma getirilecek şekilde geçirmek için dikkat edilmesi gereken noktaları içerir.Tanıtım iş yükünü kullanarak Performans ölçümleri gerçekleştirme yönergeleri- ostress'i yükleme ve çalıştırma yönergelerini, iş yükünü yönlendirmek için kullanılan bir araç ve tanıtım iş yükünün kendisini çalıştırma yönergelerini içerir.
Önkoşullar
-
SQL Server 2016 (13.x)
Performans testi için, üretim ortamınıza benzer belirtimlere sahip bir sunucu. Bu örnek için SQL Server için en az 16 GB bellek kullanılabilir olmalıdır. Bellek içi OLTP donanımıyla ilgili genel yönergeler için şu blog gönderisine bakın: SQL Server'da OLTP In-Memory için donanımla ilgili dikkat edilmesi gerekenler
AdventureWorks tabanlı bellek içi OLTP örneğini yükleme
Örneği yüklemek için şu adımları izleyin:
Yerel bir klasöre, örneğin
AdventureWorks2016_EXT.bak,SQLServer2016Samples.zipve https://github.com/microsoft/sql-server-samples/releases/tag/adventureworks'i indirin:C:\Temp.Transact-SQL veya SQL Server Management Studio kullanarak veritabanı yedeklemesini geri yükleyin:
Veri dosyasının hedef klasörünü ve dosya adını tanımlayın, örneğin:
H:\DATA\AdventureWorks2022_Data.mdfGünlük dosyasının hedef klasörünü ve dosya adını tanımlayın, örneğin:
I:\DATA\AdventureWorks2022_log.ldf- Günlük dosyası, en yüksek performans için ideal olarak SSD veya PCIe depolama gibi düşük gecikme süreli bir sürücü olan veri dosyasından farklı bir sürücüye yerleştirilmelidir.
Örnek T-SQL betiği:
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Örnek betikleri ve iş yükünü görüntülemek için dosyayı
SQLServer2016Samples.zipyerel bir klasöre açın. İş yükünü çalıştırma yönergeleri için dosyayaIn-Memory OLTP\readme.txtbaşvurun.
Örnek tabloların ve yordamların açıklaması
Örnek, AdventureWorks2025içindeki mevcut tabloları temel alarak ürünler ve satış siparişleri için yeni tablolar oluşturur. Yeni tabloların şeması, bu bölümün ilerleyen bölümlerinde açıklandığı gibi, birkaç farklılığı olan mevcut tablolara benzer.
Bellek için optimize edilmiş yeni tablolar son ekini _inmem taşır. Örnek ayrıca son eki _ondisk taşıyan karşılık gelen tabloları da içerir. Bu tablolar, bellek için iyileştirilmiş tablolarla sisteminizdeki disk tabanlı tabloların performansı arasında bire bir karşılaştırma yapmak için kullanılabilir.
Performans karşılaştırması için iş yükünde kullanılan bellek-iyileştirilmiş tablolar tamamen dayanıklıdır ve tamamen günlüklenmiştir. Performans kazancı elde etmek için dayanıklılık veya güvenilirliknden ödün vermezler.
Bu örneğin hedef iş yükü, ürünler ve indirimler hakkında da bilgi aldığımız satış siparişi işlemedir. Bu amaçla SalesOrderHeader, SalesOrderDetail, Product, SpecialOfferve SpecialOfferProducttablolarını kullanırız.
satış siparişlerini eklemek ve belirli bir satış siparişinin sevkiyat bilgilerini güncelleştirmek için Sales.usp_InsertSalesOrder_inmem ve Sales.usp_UpdateSalesOrderShipInfo_inmemolmak üzere iki yeni saklı yordam kullanılır.
Yeni şema Demo, tanıtım iş yükünü yürütmek için yardımcı tablolar ve saklı yordamlar içerir.
Açıkçası, In-Memory OLTP örneği aşağıdaki nesneleri AdventureWorks2025ekler:
Örnek tarafından eklenen tablolar
Yeni tablolar
Sales.SalesOrderHeader_inmem
- Satış siparişleri hakkındaki üst bilgi. Her satış siparişinin bu tabloda bir satırı vardır.
Sales.SalesOrderDetail_inmem
- Satış siparişlerinin ayrıntıları. Bir satış siparişinin her satır öğesinin bu tabloda bir satırı vardır.
Sales.SpecialOffer_inmem
- Her özel teklifle ilişkili indirim yüzdesi de dahil olmak üzere özel teklifler hakkında bilgi.
Sales.SpecialOfferProduct_inmem
- Özel teklifler ve ürünler arasındaki başvuru tablosu. Her özel teklifte sıfır veya daha fazla ürün bulunabilir ve her ürün sıfır veya daha fazla özel teklifte yer alabilir.
Production.Product_inmem
- Liste fiyatları dahil olmak üzere ürünlerle ilgili bilgiler.
Demo.DemoSalesOrderDetailSeed
- Örnek satış siparişlerini oluşturmak için tanıtım iş yükünde kullanılır.
Tabloların disk tabanlı varyasyonları:
Sales.SalesOrderHeader_ondiskSales.SalesOrderDetail_ondiskSales.SpecialOffer_ondiskSales.SpecialOfferProduct_ondiskProduction.Product_ondisk
Özgün disk tabanlı ve bellek için iyileştirilmiş yeni tablolar arasındaki farklar
Genellikle, bu örnek tarafından sunulan yeni tablolar özgün tablolarla aynı sütunları ve aynı veri türlerini kullanır. Ancak, birkaç fark vardır. Bu bölümdeki farkları ve değişiklikler için bir gerekçeyi listeleyeceğiz.
Satışlar.SatışSiparişBaşlığı_inmem
Varsayılan kısıtlamalar bellek için iyileştirilmiş tablolarda desteklenir ve çoğu varsayılan kısıtlama olduğu gibi taşındı. Ancak, özgün tablo
Sales.SalesOrderHeader,OrderDateveModifiedDatesütunları için geçerli tarihi otomatik olarak alan iki varsayılan kısıtlama içerir. Çok eşzamanlılık içeren yüksek işlem hacmi sipariş işleme iş yükünde, herhangi bir küresel kaynak bir çekişme noktası haline gelebilir. Sistem zamanı, küresel bir kaynak olduğundan, satış siparişlerini ekleyen In-Memory OLTP iş yükünü çalıştırırken bir darboğaz oluşturabileceğini gözlemledik, özellikle de satış siparişi üst bilgisindeki ve satış siparişi ayrıntılarındaki birden fazla sütun için sistem zamanının alınması gerekiyorsa. Bu örnekte, eklenen her satış siparişi için sistem saati yalnızca bir kez alınarak, bu değerSalesOrderHeader_inmemdepolama yordamındaSalesOrderDetail_inmemveSales.usp_InsertSalesOrder_inmemiçindeki tarih saat sütunları için kullanılarak sorun çözülmektedir.Diğer ad kullanıcı tanımlı veri türleri (UDT) - Özgün tablo
dbo.OrderNumbervedbo.AccountNumberadlı iki diğer ad UDT'sini, sırasıylaPurchaseOrderNumberveAccountNumbersütunları için kullanır. SQL Server 2016 (13.x), bellek iyileştirmeli tablolar için diğer ad UDT'yi desteklemediğinden, yeni tablolar sırasıyla nvarchar(25) ve nvarchar(15) sistem veri türlerini kullanır.Dizin anahtarlarında boş değer atanabilir sütunlar - Özgün tabloda sütun
SalesPersonIDboş değer atanabilirken, yeni tablolarda sütun boş değer atanamaz ve (-1) değeriyle bir varsayılan kısıtlaması vardır. Bunun nedeni, bellek için iyileştirilmiş tablolardaki dizinlerin dizin anahtarında NULL değer atanabilir sütunlar bulunduramamasıdır; bu durumda -1, NULL için bir tampon görevi görür.Hesaplanan sütunlar - SQL Server 2016 (13.x) bellek iyileştirmeli tablolarda hesaplanan sütunları desteklemediği için
SalesOrderNumberveTotalDuehesaplanan sütunlar atlanır. Yeni görünümSales.vSalesOrderHeader_extended_inmemSalesOrderNumberveTotalDuesütunlarını yansıtır. Bu nedenle, bu sütunlar gerekiyorsa bu görünümü kullanabilirsiniz.- Şunlar için geçerlidir: SQL Server 2017 (14.x). SQL Server 2017(14.x) sürümünden başlayarak, hesaplanan sütunlar bellek için iyileştirilmiş tablolarda ve dizinlerde desteklenir.
Yabancı anahtar kısıtlamaları SQL Server 2016'da (13.x) bellek için iyileştirilmiş tablolar için desteklenir, ancak yalnızca başvuruda bulunılan tablolar da bellek için iyileştirilmişse desteklenir. Bellek için optimize edilmiş tablolara da taşınan tablolara başvuran yabancı anahtarlar taşınmış tablolarda saklanırken, diğer yabancı anahtarlar atlanır. Buna ek olarak,
SalesOrderHeader_inmemörnek iş yükündeki sıcak bir tablodur ve yabancı anahtar kısıtlamaları, tüm DML işlemleri için ek işlem gerektirir, çünkü bu kısıtlamalarda referans verilen diğer tüm tablolarda arama yapılmasını gerektirir. Bu nedenle, uygulamanınSales.SalesOrderHeader_inmemtablosu için başvuru bütünlüğü sağladığı ve satırlar eklendiğinde başvuru bütünlüğünün doğrulanmadığı varsayılır.Rowguid - Rowguid sütunu dahil edilmemiştir. Bellek için iyileştirilmiş tablolar için uniqueidentifier desteklenirken, ROWGUIDCOL seçeneği SQL Server 2016'da (13.x) desteklenmez. Bu tür sütunlar genellikle birleştirme çoğaltması veya dosya akışı sütunları olan tablolar için kullanılır. Bu örnekte ikisi de yok.
Satış.SatışSiparişiDetayı
Varsayılan kısıtlamalar -
SalesOrderHeadergibi, sistem tarih/saatini gerektiren varsayılan kısıtlama aktarılmaz. Bunun yerine, satış siparişlerini ekleme saklı yordamı, ilk eklemede geçerli sistem tarihini/saatini eklemeyi üstlenir.Hesaplanan sütunlar - hesaplanan sütunlar
LineTotalSQL Server 2016'da (13.x) bellek için iyileştirilmiş tablolarda desteklenmediğinden, hesaplanan sütun geçirilmemiştir. Bu sütuna erişmek içinSales.vSalesOrderDetail_extended_inmemgörünümünü kullanın.Rowguid -
rowguidsütunu atlanır. Ayrıntılar içinSalesOrderHeadertablosunun açıklamasına bakın.
Üretim.Ürün
Takma Ad UDT'leri - özgün tablo, sistem veri türü bit ile eşdeğer olan kullanıcı tanımlı veri türünü
dbo.Flagkullanır. Geçirilen tablo bunun yerine bit veri türünü kullanır.Rowguid -
rowguidsütunu atlanır. Ayrıntılar içinSalesOrderHeadertablosunun açıklamasına bakın.
Satış.ÖzelTeklif
-
Rowguid -
rowguidsütunu atlanır. Ayrıntılar içinSalesOrderHeadertablosunun açıklamasına bakın.
Sales.SpecialOfferProduct
-
Rowguid -
rowguidsütunu atlanır. Ayrıntılar içinSalesOrderHeadertablosunun açıklamasına bakın.
Bellek için iyileştirilmiş tablolarda dizinler için dikkat edilmesi gerekenler
Bellek için iyileştirilmiş tablolar için temel dizin, nokta aramalarını (eşitlik koşulunda dizin arama), aralık taramalarını (eşitsizlik koşulunda dizin arama), tam dizin taramalarını ve sıralı taramaları destekleyen NONCLUSTERED dizinidir. Ayrıca, NONCLUSTERED dizinleri dizin anahtarının öndeki sütunlarında aramayı destekler. Aslında, bellek için optimize edilmiş KÜME DIŞI dizinler, geriye dönük taramalar dışında, disk tabanlı KÜME DIŞI dizinler tarafından desteklenen tüm işlemleri destekler. Bu nedenle, NONCLUSTERED dizinlerini kullanmak dizinleriniz için güvenli bir seçimdir.
HASH dizinleri, iş yükünü daha da iyileştirmek için kullanılabilir. Nokta aramaları ve satır eklemeleri için iyileştirilmiştir. Ancak, aralık taramalarını, sıralı taramaları veya öndeki dizin anahtarı sütunlarında aramayı desteklemediklerini göz önünde bulundurmanız gerekir. Bu nedenle, bu dizinler kullanılırken dikkatli olunması gerekir. Oluşturma zamanında bucket_count öğesinin belirtilmesi de gerekir. Genellikle dizin anahtarı değerlerinin sayısının bir ile iki katı arasında ayarlanmalıdır, ancak fazla tahmin edilirse genellikle bir sorun olmaz.
Daha fazla bilgi için:
- Çevrimiçi dizin işlemleri için yönergeler
- Doğru bucket_count sayısını seçme
- Memory-Optimized Tablolardaki Dizinler
Geçirilen tablolardaki dizinler demo satış siparişi işleme iş yükü için ayarlandı. İş yükü, Sales.SalesOrderHeader_inmem ve Salestablolardaki eklemelere ve nokta aramalarına dayanır.SalesOrderDetail_inmemve ayrıca Production.Product_inmem ve Sales.SpecialOffer_inmemtablolardaki birincil anahtar sütunlarında nokta aramalarına da dayanır.
Sales.SalesOrderHeader_inmem, performans nedeniyle ve iş yükü için sıralı veya aralıklı tarama gerekmadığı için tümü KARMA dizin olan üç dizine sahiptir.
HASH indeksi (
SalesOrderID) üzerinde: beklenen satış siparişi sayısı 10 milyon olduğundan bucket_count, 10 milyon olarak boyutlandırılmış ve 16 milyona yuvarlanmıştır.ÜZERINDE HASH dizini (
SalesPersonID): bucket_count 1 milyondur. Sağlanan veri kümesinde çok fazla satış elemanı yok. Ancak bu büyük bucket_count gelecekte büyümeye olanak tanır. Ayrıca, bucket_count fazla büyükse nokta sorguları için performans kaybı yaşamazsınız.ÜZERINDE HASH dizini (
CustomerID): bucket_count 1 milyondur. Sağlanan veri kümesinin çok fazla müşterisi yoktur, ancak bu gelecekte büyümeye olanak tanır.
Sales.SalesOrderDetail_inmem, performans nedeniyle ve iş yükü için sıralı veya aralıklı tarama gerekmadığı için tümü KARMA dizin olan üç dizine sahiptir.
(
SalesOrderID,SalesOrderDetailID) üzerindeki KARMA dizini: Bu birincil anahtar dizinidir ve (SalesOrderID,SalesOrderDetailID) üzerindeki aramalar seyrek olsa da, anahtar için karma dizin kullanılarak satır eklemeleri hızlandırılır. bucket_count 50 milyon olarak boyutlandırılır (67 milyona yuvarlanmış): beklenen satış siparişi sayısı 10 milyondur ve sipariş başına ortalama beş ürün olacak şekilde boyutlandırılır(
SalesOrderID) Üzerinde HASH dizini: Satış siparişine göre aramalar sık yapılır; tek bir siparişe karşılık gelen tüm satır öğelerini bulmak istiyorsunuz. beklenen satış siparişi sayısı 10 milyon olduğundan bucket_count 10 milyon (16 milyona yuvarlanmış) olarak boyutlandırılırÜZERINDE HASH dizini (
ProductID): bucket_count 1 milyondur. Sağlanan veri kümesinin çok fazla ürünü yoktur, ancak bu gelecekte büyümeye olanak tanır.
Production.Product_inmem üç dizini vardır
HASH dizini (
ProductID) üzerinde:ProductIDaramaları, demo iş yükü için kritik yolda olduğundan bu bir hash dizinidir.NameKÜMESİZ dizin: Bu, ürün adlarının sıralı bir şekilde taranmasına olanak tanır.(
ProductNumber) üzerinde NONCLUSTERED indeks: Bu, ürün numaralarının sıralı taramalarına izin verir.
Sales.SpecialOffer_inmem üzerinde bir KARMA dizini vardır (SpecialOfferID): özel tekliflerin nokta aramaları, tanıtım iş yükünün kritik bölümünde yer alır.
bucket_count, gelecekteki büyümeyi sağlamak için 1 milyon olarak boyutlandırılır.
Sales.SpecialOfferProduct_inmem demo iş yükünde başvurulmuyor ve bu nedenle bu tablo için karma dizinlerin kullanılması gerekmemektedir, iş yükünü optimize etmek üzere kullanılan (SpecialOfferID, ProductID) ve (ProductID) üzerindeki dizinler KÜMELENMEMİŞtir.
Önceki örnekte, bazı demet sayıları büyük boyutludur, ancak SalesOrderHeader_inmem ve SalesOrderDetail_inmem üzerindeki dizinler için demet sayıları büyük boyutlu değildir: bunlar yalnızca 10 milyon satış siparişi için boyutlandırılmıştır. Bu, düşük bellek kullanılabilirliğine sahip sistemlere yüklenmesine izin vermek için yapıldı, ancak bu durumlarda, demo iş yükü bellek yetersizliği hatasıyla başarısız olur. 10 milyon satış siparişinin ötesinde ölçeklendirmek istiyorsanız, kova sayısını buna göre artırmaktan tereddüt etmeyin.
Bellek kullanımıyla ilgili dikkat edilmesi gerekenler
Örnek veritabanında hem tanıtım iş yükünü çalıştırmadan önce hem de çalıştırdıktan sonra bellek kullanımı, bellek için iyileştirilmiş tablolar için Bellek kullanımıbölümünde ele alınmaktadır.
Örnek tarafından eklenen saklı yordamlar
Satış siparişi eklemek ve sevkiyat ayrıntılarını güncelleştirmek için iki önemli depolanmış prosedür şunlardır:
Sales.usp_InsertSalesOrder_inmemVeritabanına yeni bir satış siparişi ekler ve bu satış siparişi için
SalesOrderIDçıktısını üretir. Giriş parametreleri olarak, satış siparişi başlığının ve siparişteki satır öğelerinin ayrıntılarını alır.Çıkış parametresi:
-
@SalesOrderID int -
SalesOrderIDyeni eklenen satış siparişi için
-
@SalesOrderID int -
Giriş parametreleri (gerekli):
- @DueDatedatetime2
- @CustomerIDint
- @BillToAddressIDint
- @ShipToAddressIDint
- @ShipMethodIDint
-
@SalesOrderDetails
Sales.SalesOrderDetailType_inmem- siparişin satır öğelerini içeren bir tablo değerli parametre (TVP)
Giriş parametreleri (isteğe bağlı):
- @Statustinyint
- @OnlineOrderFlagbit
- @PurchaseOrderNumbernvarchar(25)
- @AccountNumbernvarchar(15)
- @SalesPersonIDint
- @TerritoryIDint
- @CreditCardIDint
- @CreditCardApprovalCodevarchar(15)
- @CurrencyRateIDint
- @Commentnvarchar(128)
Sales.usp_UpdateSalesOrderShipInfo_inmemBelirli bir satış siparişi için sevkiyat bilgilerini güncelleştirin. Bu, satış siparişinin tüm satır öğeleri için sevkiyat bilgilerini de güncelleştirir.
Bu, aynı sırayı güncelleştiren eşzamanlı işlemlerle (beklenmeyen) olası çakışmalarla başa çıkmak için yeniden deneme mantığıyla
Sales.usp_UpdateSalesOrderShipInfo_nativeyerel olarak derlenmiş saklı yordamlar için bir sarmalayıcı yordamıdır. Daha fazla bilgi için bkz. yeniden deneme mantığı.
Sales.usp_UpdateSalesOrderShipInfo_native- Bu, sevkiyat bilgilerine yönelik güncellemeyi işlemekte olan yerel olarak derlenmiş saklı yordamdır. Kapsayıcı saklı yordam
Sales.usp_UpdateSalesOrderShipInfo_inmem'dan çağrılmalıdır. İstemci hatalarla başa çıkabiliyorsa ve yeniden deneme mantığını uyguluyorsa, sarmalayıcı saklı yordamını kullanmak yerine bu yordamı doğrudan çağırabilirsiniz.
- Bu, sevkiyat bilgilerine yönelik güncellemeyi işlemekte olan yerel olarak derlenmiş saklı yordamdır. Kapsayıcı saklı yordam
Tanıtım amaçlı iş yükü için aşağıdaki saklı prosedür kullanılır.
Demo.usp_DemoReset- Tanıtımı,
SalesOrderHeaderveSalesOrderDetailtablolarını boşaltıp yeniden tohumlayarak baştan başlatır.
- Tanıtımı,
Aşağıdaki saklı yordamlar, etki alanı ve referans bütünlüğünü garanti ederken bellek için iyileştirilmiş tablolara ekleme yapmak ve bu tablolardan silme işlemi gerçekleştirmek için kullanılır.
Production.usp_InsertProduct_inmemProduction.usp_DeleteProduct_inmemSales.usp_InsertSpecialOffer_inmemSales.usp_DeleteSpecialOffer_inmemSales.usp_InsertSpecialOfferProduct_inmem
Son olarak, etki alanı ve referans bütünlüğünü doğrulamak için aşağıdaki saklı yordam kullanılır.
dbo.usp_ValidateIntegrityİsteğe bağlı parametre: @object_id - Bütünlüğünün doğrulanması için nesnenin kimliği
Bu prosedür, doğrulanması gereken bütünlük kuralları için
dbo.DomainIntegrity,dbo.ReferentialIntegrityvedbo.UniqueIntegritytablolarını kullanır. Örnek,AdventureWorks2025veritabanındaki özgün tabloların mevcut denetim, yabancı anahtar ve benzersiz kısıtlamalarına göre bu tabloları doldurur.Bütünlük denetimlerini gerçekleştirmek için gereken T-SQL'i oluşturmak için
dbo.usp_GenerateCKCheck,dbo.usp_GenerateFKCheckvedbo.GenerateUQCheckyardımcı yordamlarına dayanır.
Demo yükünü kullanarak performans ölçümleri
ostress , Microsoft CSS SQL Server destek ekibi tarafından geliştirilen bir komut satırı aracıdır. Bu araç sorguları yürütmek veya saklı yordamları paralel olarak çalıştırmak için kullanılabilir. Belirli bir T-SQL deyimini paralel olarak çalıştıracak iş parçacığı sayısını yapılandırabilir ve deyimin bu iş parçacığında kaç kez yürütülmesi gerektiğini belirtebilirsiniz; ostress iş parçacıklarını çalıştırır ve deyimini tüm iş parçacıklarında paralel olarak yürütür. Tüm iş parçacıkları için yürütme tamamlandıktan sonra, ostress tüm iş parçacıklarının yürütmeyi tamamlaması için geçen süreyi bildirir.
Ostress'i yükleme
ostress , Rapor İşaretleme Dili (RML) Yardımcı Programlarının bir parçası olarak yüklenir; ostress için tek başına yükleme yoktur.
Yükleme adımları:
RML yardımcı programları için x64 yükleme paketini şu sayfadan indirin ve çalıştırın: SQL Server için RML'yi indirin
Belirli dosyaların kullanımda olduğunu belirten bir iletişim kutusu varsa ,'Devam'ı seçin
Ostress'i çalıştırma
Ostress komut satırı isteminden çalıştırılır. Aracı, RML Yardımcı Programlarının bir parçası olarak yüklenen RML Cmd İsteminden çalıştırmak en uygun seçenektir.
RML Cmd İstemini açmak için şu yönergeleri izleyin:
Windows'ta, Windows tuşunu seçerek başlat menüsünü açın ve rmlyazın. Arama sonuçları listesinde yer alan RML Cmd İstemi'ni seçin.
Komut isteminin RML Yardımcı Programları yükleme klasöründe bulunduğundan emin olun.
Ostress için komut satırı seçenekleri, ostress.exe herhangi bir komut satırı seçeneği olmadan çalıştırıldığında görülebilir. Bu örnekle ostress çalıştırmak için dikkate alınması gereken ana seçenekler şunlardır:
| Seçenek | Description |
|---|---|
-S |
Bağlanacak SQL Server örneğinin adı. |
-E |
Bağlanmak için Windows kimlik doğrulamasını kullanma (varsayılan); SQL Server kimlik doğrulaması kullanıyorsanız, sırasıyla kullanıcı adı ve parolayı belirtmek için ve -U seçeneklerini -P kullanın. |
-d |
Bu örnek AdventureWorks2025için veritabanının adı. |
-Q |
Yürütülecek T-SQL deyimi. |
-n |
Her giriş dosyasını/sorgusunu işleyen bağlantı sayısı. |
-r |
Her giriş dosyasını/sorgusunu yürütmek için her bağlantı için yineleme sayısı. |
Tanıtım iş yükü
Tanıtım iş yükünde kullanılan ana saklı yordam Sales.usp_InsertSalesOrder_inmem/ondisk. Aşağıdaki örnekteki betik, örnek verilerle tablo değerli bir parametre (TVP) oluşturur ve beş satır öğeli bir satış siparişi ekleme yordamını çağırır.
İstemcilerin satış siparişlerini eşzamanlı olarak ekleme benzetimini yapmak amacıyla, saklı yordam çağrılarını paralel olarak yürütmek için Ostress aracı kullanılır.
Her stres çalıştırmasının ardından Demo.usp_DemoResetyürüterek demoyu sıfırlayın. Bu yordam bellek için iyileştirilmiş tablolardaki satırları siler, disk tabanlı tabloları kesir ve bir veritabanı denetim noktası yürütür.
Aşağıdaki betik, bir satış siparişi işleme iş yükünün benzetimini yapmak için eşzamanlı olarak yürütülür:
DECLARE @i AS INT = 0, @od AS Sales.SalesOrderDetailType_inmem, @SalesOrderID AS INT, @DueDate AS DATETIME2 = sysdatetime(), @CustomerID AS INT = RAND() * 8000, @BillToAddressID AS INT = RAND() * 10000, @ShipToAddressID AS INT = RAND() * 10000, @ShipMethodID AS 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
EXECUTE Sales.usp_InsertSalesOrder_inmem
@SalesOrderID OUTPUT,
@DueDate,
@CustomerID,
@BillToAddressID,
@ShipToAddressID,
@ShipMethodID,
@od;
SET @i + = 1;
END
Bu betikle oluşturulan her örnek sipariş, bir WHILE döngüsü ile yürütülen 20 saklı yordama 20 kez eklenir. Döngü, veritabanının örnek sırayı oluşturmak için kullanıldığı gerçeğini hesaba eklemek için kullanılır. Tipik üretim ortamlarında orta katman uygulaması eklenecek satış siparişini oluşturur.
Daha önceki betik, satış siparişlerini bellekle optimize edilmiş tablolara yerleştirir. Satış siparişlerini disk tabanlı tablolara eklemek için betik, _inmem öğesinin iki kez _ondisk ile değiştirilmesiyle türetilir.
Betikleri birkaç eşzamanlı bağlantı kullanarak yürütmek için ostress aracını kullanırız. Bağlantı sayısını denetlemek için parametresini -n ve betiğin her bağlantıda kaç kez yürütülür denetlemek için parametresini r kullanırız.
İş yükünü çalıştırma
Büyük ölçekte test etmek için 100 bağlantı kullanarak 10 milyon satış siparişi ekleriz. Bu test, mütevazı bir sunucuda (örneğin, 8 fiziksel, 16 mantıksal çekirdek) ve günlükler için temel SSD depolama alanıyla makul bir şekilde çalışır. Test donanımınızda iyi performans göstermiyorsa Yavaş çalışan testlerde sorun giderme bölümüne bakın. Bu test için stres düzeyini azaltmak istiyorsanız parametresini -ndeğiştirerek bağlantı sayısını azaltın. Örneğin, bağlantı sayısını 40'a düşürmek için parametresini -n100 olarak -n40değiştirin.
İş yükü için performans ölçüsü olarak, iş yükünü çalıştırdıktan sonra tarafından ostress.exe bildirilen geçen süreyi kullanırız.
Aşağıdaki yönergeler ve ölçümler, 10 milyon satış siparişi ekleyen bir iş yükü kullanır. 1 milyon satış siparişi ekleyen ölçeği azaltılmış iş yükünü çalıştırma yönergeleri için, arşivin bir parçası olan içindeki In-Memory OLTP\readme.txt yönergelere SQLServer2016Samples.zip bakın.
Bellek için iyileştirilmiş tablolar
başlangıç olarak iş yükünü bellek için iyileştirilmiş tablolarda çalıştırıyoruz. Aşağıdaki komut, her biri 5.000 yineleme gerçekleştiren 100 iş parçacığı açar. Her yineleme ayrı işlemlere 20 satış siparişi ekler. Veritabanının eklenecek verileri oluşturmak için kullanıldığı gerçeğini telafi etmek için yineleme başına 20 ekleme vardır. Bu toplam 20 * 5.000 * 100 = 10.000.000 satış siparişi kaydı verir.
RML Komut İstemi'ni açın ve aşağıdaki komutu yürütün:
Kopyala düğmesini seçerek komutu kopyalayın ve RML Yardımcı Programları komut istemine yapıştırın.
ostress.exe -n100 -r5000 -S. -E -dAdventureWorks2022 -q -Q"DECLARE @i AS INT = 0, @od AS Sales.SalesOrderDetailType_inmem, @SalesOrderID AS INT, @DueDate AS DATETIME2 = SYSDATETIME(), @CustomerID AS INT = RAND() * 8000, @BillToAddressID AS INT = RAND() * 10000, @ShipToAddressID AS INT = RAND() * 10000, @ShipMethodID AS 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 EXECUTE Sales.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; SET @i + = 1; END"
Toplam 8 fiziksel (16 mantıksal) çekirdeği olan bir test sunucusunda bu işlem 2 dakika 5 saniye sürdü. 24 fiziksel (48 mantıksal) çekirdeği olan ikinci bir test sunucusunda bu işlem 1 dakika 0 saniye sürdü.
İş yükü çalışırken CPU kullanımını gözlemleyin, örneğin görev yöneticisini kullanın. CPU kullanımının 100%yakın olduğunu görürsünüz. Böyle bir durum söz konusu değilse günlük GÇ tıkanıklığınız vardır. Detaylı bilgi için bkz. Yavaş çalışan testlerde sorun giderme.
Disk tabanlı tablolar
Aşağıdaki komut, iş yükünü disk tabanlı tablolarda çalıştırır. Bu iş yükünün yürütülmesi biraz zaman alabilir ve bunun nedeni büyük ölçüde sistemdeki mandal çekişmesidir. Bellek için iyileştirilmiş tablolar mandalsızdır ve bu nedenle bu sorundan muzdarip değildir.
RML Cmd İstemi'ni açın ve aşağıdaki komutu yürütün.
Kopyala düğmesini seçerek komutu kopyalayın ve RML Yardımcı Programları komut istemine yapıştırın.
ostress.exe -n100 -r5000 -S. -E -dAdventureWorks2022 -q -Q"DECLARE @i AS INT = 0, @od AS Sales.SalesOrderDetailType_ondisk, @SalesOrderID AS INT, @DueDate AS DATETIME2 = sysdatetime(), @CustomerID AS INT = RAND() * 8000, @BillToAddressID AS INT = RAND() * 10000, @ShipToAddressID AS INT = RAND() * 10000, @ShipMethodID AS 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 EXECUTE Sales.usp_InsertSalesOrder_ondisk @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; SET @i + = 1; END"
Toplam 8 fiziksel (16 mantıksal) çekirdeği olan bir test sunucusunda bu işlem 41 dakika 25 saniye sürdü. 24 fiziksel (48 mantıksal) çekirdeği olan ikinci bir test sunucusunda bu işlem 52 dakika 16 saniye sürdü.
Bu testte bellek için iyileştirilmiş tablolarla disk tabanlı tablolar arasındaki performans farkının ana faktörü, disk tabanlı tablolar kullanıldığında SQL Server'ın CPU'nun tam olarak kullanamamadır. Bunun nedeni mandal çekişmesidir: eşzamanlı işlemler aynı veri sayfasına yazmaya çalışır; Mandallar, bir kerede yalnızca bir işlemin sayfaya yazabilmesini sağlamak için kullanılır. In-Memory OLTP altyapısı mandalsızdır ve veri satırları sayfalarda düzenlenmemiştir. Bu nedenle, eşzamanlı işlemler birbirlerinin eklemelerini engellemez, bu nedenle SQL Server'ın CPU'nun tam olarak kullanılmasını sağlar.
İş yükü çalışırken, örneğin görev yöneticisini kullanarak CPU kullanımını gözlemleyebilirsiniz. Disk tabanlı tablolarda CPU kullanımının 100%uzak olduğunu görürsünüz. 16 mantıksal işlemciye sahip bir test yapılandırmasında, kullanım 24%çevresinde görünür.
İsteğe bağlı olarak, performans sayacı \SQL Server:Latches\Latch Waits/secPerformans İzleyicisi'ni kullanarak saniye başına mandal bekleme sayısını görüntüleyebilirsiniz.
Demoyu sıfırla
Tanıtım sürümünü sıfırlamak için RML Cmd İstemi'ni açın ve aşağıdaki komutu yürütün.
ostress.exe -S. -E -dAdventureWorks2022 -Q"EXEC Demo.usp_DemoReset"
Donanıma bağlı olarak, bunun çalıştırılması birkaç dakika sürebilir.
Her tanıtım çalıştırması sonrasında sıfırlama yapmanızı öneririz. Bu iş yükü yalnızca ekleme olduğundan, her çalıştırma daha fazla bellek tüketir ve bu nedenle belleğin tükenmesini önlemek için bir sıfırlama gerekir. Bir çalıştırmadan sonra tüketilen bellek miktarı, iş yükü çalıştırıldıktan sonra Bellek kullanımıBölümünde açıklanmıştır.
Yavaş çalışan testlerde sorun giderme
Test sonuçları genellikle donanıma ve test çalıştırmasında kullanılan eşzamanlılık düzeyine göre değişir. Sonuçlar beklendiği gibi değilse aranacak birkaç şey:
Eşzamanlı işlem sayısı: İş yükünü tek bir iş parçacığında çalıştırırken In-Memory OLTP ile performans artışı büyük olasılıkla 2 kattan azdır. Mandal çekişmesi yalnızca yüksek düzeyde eşzamanlılık varsa önemli bir sorundur.
SQL Server için kullanılabilir çekirdek sayısının düşük olması: Bu, sql için kullanılabilen çekirdek sayısı kadar eşzamanlı işlem yürütebildiği için sistemde düşük eşzamanlılık düzeyi olduğu anlamına gelir.
- Belirti: İş yükünü disk tabanlı tablolarda çalıştırırken CPU kullanımı yüksekse bu, eşzamanlılık eksikliğine işaret eden çok fazla çekişme olmadığı anlamına gelir.
Günlük sürücüsünün hızı: Günlük sürücüsü sistemdeki işlem aktarım hızı düzeyine ayak uyduramıyorsa, iş yükü günlük GÇ'de performans sorununa neden olur. Günlüğe kaydetme In-Memory OLTP ile daha verimli olsa da, günlük G/Ç bir darboğaz oluşturuyorsa olası performans kazancı sınırlıdır.
- Belirti: CPU kullanımı 100% civarında değilse veya iş yükünü bellek için iyileştirilmiş tablolarda çalıştırırken çok dalgalıysa, günlük GÇ darboğazı yaşanıyor olabilir. Bu, Kaynak İzleyicisi'ni açıp günlük sürücüsünün kuyruk uzunluğuna bakarak doğrulanabilir.
Örnekte bellek ve disk alanı kullanımı
Aşağıdaki örnekte, örnek veritabanı için bellek ve disk alanı kullanımı açısından neler bekleyebileceğiniz açıklanmaktadır. Ayrıca 16 mantıksal çekirdeği olan bir test sunucusundan elde ettiğimiz sonuçları da gösteririz.
Bellek-iyileştirilmiş tabloların bellek kullanımı
Veritabanının genel kullanımı
Aşağıdaki sorgu, sistemdeki In-Memory OLTP için toplam bellek kullanımını elde etmek için kullanılabilir.
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Veritabanı yeni oluşturulduktan sonra anlık görüntü:
| tür | isim | sayfalar_MB |
|---|---|---|
| MEMORYCLERK_XTP | Varsayılan | 94 |
| MEMORYCLERK_XTP | DB_ID_5 | 877 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
Varsayılan bellek yöneticileri, sistem çapında bellek yapıları içerir ve nispeten küçüktür. Bu örnekte kimliği 5 database_id olan (örneğinizde farklılık gösterebilir) kullanıcı veritabanı için bellek katibi yaklaşık 900 MB'tır.
Tablo başına bellek kullanımı
Aşağıdaki sorgu, tek tek tabloların ve dizinlerinin bellek kullanımında detaya gitmek için kullanılabilir:
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 AS dms
INNER JOIN sys.tables AS t
ON dms.object_id = t.object_id
WHERE t.type = 'U';
Aşağıdaki tabloda, örneğin yeni bir yüklemesi için bu sorgunun sonuçları görüntülenir:
| Tablo adı | 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 |
Gördüğünüz gibi tablolar oldukça küçüktür: SalesOrderHeader_inmem yaklaşık 7 MB ve SalesOrderDetail_inmem boyutu yaklaşık 15 MB'tır.
Burada dikkat çekici olan, tablo verilerinin boyutuyla karşılaştırıldığında dizinler için ayrılan belleğin boyutudur. Bunun nedeni örnekteki karma dizinlerin daha büyük bir veri boyutu için önceden oluşturulmuş olmasıdır. Karma dizinlerin boyutu sabittir ve bu nedenle tablodaki verilerin boyutuyla büyümez.
İş yükünü çalıştırdıktan sonra bellek kullanımı
10 milyon satış siparişi eklendikten sonra, tüm bellek kullanımı aşağıdaki sorguya benzer:
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Sonuç kümesi aşağıdadır.
type |
name |
pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Varsayılan | 146 |
| MEMORYCLERK_XTP | DB_ID_5 | 7374 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
Gördüğünüz gibi SQL Server, örnek veritabanındaki bellek için iyileştirilmiş tablolar ve dizinler için 8 GB'ın altında bir bit kullanıyor.
Bir örnek çalıştırmadan sonra tablo başına ayrıntılı bellek kullanımına bakın:
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 AS dms
INNER JOIN sys.tables AS t
ON dms.object_id = t.object_id
WHERE t.type = 'U';
Sonuç kümesi aşağıdadır.
Table name |
memory_allocated_for_table_kb |
memory_allocated_for_indexes_kb |
|---|---|---|
| SalesOrderDetail_inmem | 5113761 | 663552 |
| DemoSatışSiparişDetayTohum | 64 | 10368 |
| ÖzelTeklif_inmem | 2 | 8192 |
| SatışSiparişiBaşlık_inmem | 1575679 | 147456 |
| Product_inmem | 111 | 12032 |
| SpecialTeklifÜrünü_inmem | 64 | 3712 |
| DemoSalesOrderHeaderSeed | 1984 | 5504 |
Toplamda yaklaşık 6,5 GB veri görebiliriz. Tablodaki SalesOrderHeader_inmem dizinlerin boyutu ve SalesOrderDetail_inmem satış siparişlerini eklemeden önce dizinlerin boyutuyla aynıdır. Her iki tablo da karma dizinler kullandığından ve karma dizinler statik olduğundan dizin boyutu değişmedi.
Demo resetten sonra
Saklanan yordam Demo.usp_DemoReset, demo'yu sıfırlamak için kullanılabilir. Tablo SalesOrderHeader_inmem ve SalesOrderDetail_inmem'deki verileri siler, ve verileri orijinal tablolar SalesOrderHeader ve SalesOrderDetail'den yeniden doldurur.
Artık tablolardaki satırlar silinmiş olsa da bu, belleğin hemen geri kazanıldığı anlamına gelmez. SQL Server, gerektiğinde arka planda bellek için iyileştirilmiş tablolarda silinen satırlardan belleği geri alır. Tanıtım sıfırlamasından hemen sonra sistemde işlemsel iş yükü olmadığından silinen satırlardaki belleğin henüz geri kazanılmadığını görürsünüz:
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Sonuç kümesi aşağıdadır.
type |
name |
pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Varsayılan | 2261 |
| MEMORYCLERK_XTP | DB_ID_5 | 7396 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
Bu beklenen bir durumdur: İşlem iş yükü çalışırken bellek geri kazanılır.
Tanıtım iş yükünün ikinci bir çalıştırmasını başlatırsanız, daha önce silinen satırlar temizlendiğinden başlangıçta bellek kullanımının azaldığını görürsünüz. Bir noktada, iş yükü bitene kadar bellek boyutu yeniden artar. Tanıtım sıfırlama işleminden sonra 10 milyon satır eklendiğinde, bellek kullanımı ilk çalıştırma sonucundaki kullanımla neredeyse aynıdır. Mesela:
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Sonuç kümesi aşağıdadır.
type |
name |
pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Varsayılan | 1863 |
| MEMORYCLERK_XTP | DB_ID_5 | 7390 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
| MEMORYCLERK_XTP | Varsayılan | 0 |
Bellek için iyileştirilmiş tablolar için disk kullanımı
Belirli bir zamanda veritabanının denetim noktası dosyalarının genel disk içi boyutu şu sorgu kullanılarak bulunabilir:
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
İlk durum
Başlangıçta örnek dosya grubu ve örnek bellek için iyileştirilmiş tablolar oluşturulduğunda, birkaç denetim noktası dosyası önceden oluşturulur ve sistem dosyaları doldurmaya başlar. Önceden oluşturulan denetim noktası dosyalarının sayısı sistemdeki mantıksal işlemci sayısına bağlıdır. Örnek başlangıçta çok küçük olduğundan, ilk oluşturma işleminden sonra önceden oluşturulmuş dosyalar çoğunlukla boş olur.
Aşağıdaki kod, 16 mantıksal işlemciye sahip bir makinedeki örneğin ilk disk içi boyutunu gösterir:
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Sonuç kümesi aşağıdadır.
| MB cinsinden disk içi boyut |
|---|
| 2312 |
Gördüğünüz gibi, 2,3 GB olan denetim noktası dosyalarının disk içi boyutu ile 30 MB'a yakın gerçek veri boyutu arasında büyük bir tutarsızlık vardır.
Disk alanı kullanımının nereden geldiğine daha yakından baktığınızda aşağıdaki sorguyu kullanabilirsiniz. Bu sorgu tarafından döndürülen disk boyutu yaklaşık olarak 5 (BACKUP/HA için GEREKLI), 6 (TOMBSTONE'A GEÇİşTE) veya 7 (TOMBSTONE) durumundaki dosyalar içindir.
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;
Örneğin ilk durumu için sonuç, 16 mantıksal işlemciye sahip bir sunucu için aşağıdaki tabloya benzer:
| durum_açıklaması | file_type_desc | saymak | diskteki boyut MB |
|---|---|---|---|
| ÖNCEDEN OLUŞTURULMUŞ | VERİ | 16 | 2048 |
| ÖNCEDEN OLUŞTURULMUŞ | DELTA | 16 | 128 |
| YAPIM AŞAMASINDA | VERİ | 1 | 128 |
| YAPIM AŞAMASINDA | DELTA | 1 | 8 |
Gördüğünüz gibi, alanın çoğu önceden oluşturulmuş veriler ve delta dosyaları tarafından kullanılır. SQL Server, mantıksal işlemci başına bir çift (veri, delta) dosyası oluşturmuştur. Ayrıca, bu dosyalara veri eklemeyi daha verimli hale getirmek için veri dosyaları 128 MB ve delta dosyaları 8 MB olarak önceden hazır hale getirilir.
Bellek için iyileştirilmiş tablolardaki gerçek veriler tek veri dosyasındadır.
İş yükünü çalıştırdıktan sonra
10 milyon satış siparişi ekleyen tek bir test çalıştırmasının ardından, disk üzerindeki genel boyut şuna benzer (16 çekirdekli test sunucusu için):
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Sonuç kümesi aşağıdadır.
| MB cinsinden disk içi boyut |
|---|
| 8828 |
Diskteki boyut 9 GB'a yakındır ve bu da verilerin bellek içi boyutuna yakındır.
Çeşitli durumlarda denetim noktası dosyalarının boyutlarına daha yakından bakmak:
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;
Sonuç kümesi aşağıdadır.
state_desc |
file_type_desc |
count |
on-disk size MB |
|---|---|---|---|
| ÖNCEDEN OLUŞTURULMUŞ | VERİ | 16 | 2048 |
| ÖNCEDEN OLUŞTURULMUŞ | DELTA | 16 | 128 |
| YAPIM AŞAMASINDA | VERİ | 1 | 128 |
| YAPIM AŞAMASINDA | DELTA | 1 | 8 |
Denetim noktaları kapatıldığında kullanıma hazır 16 çift önceden oluşturulmuş dosyamız var.
Yapım aşamasında olan ve geçerli denetim noktası kapatılana kadar kullanılan bir çift vardır. Etkin denetim noktası dosyalarıyla birlikte bu, bellekteki 6,5 GB veri için yaklaşık 6,5 GB disk kullanımı sağlar. Dizinlerin diskte kalıcı olmadığını ve bu nedenle diskteki genel boyutun bu durumda bellekteki boyuttan daha küçük olduğunu hatırlayın.
Demo resetten sonra
Tanıtım sıfırlama işlemi sonrasında, sistemde işlemsel bir iş yükü yoksa ve veritabanı denetim noktaları bulunmuyorsa, disk alanı hemen geri kazanılmaz. Denetim noktası dosyalarının çeşitli aşamalarında taşınarak sonunda atılması için, denetim noktası dosyalarının birleştirilmesini ve çöp toplamanın başlatılmasını sağlamak amacıyla çeşitli denetim noktaları ve günlük kesme işlemleri gerçekleşmelidir. Bunlar, sistemde işlemsel bir iş yükünüz varsa (ve TAM kurtarma modelini kullanıyorsanız normal günlük yedeklemeleri alıyorsanız) otomatik olarak gerçekleşir, ancak bir tanıtım senaryosunda olduğu gibi sistem boşta olduğunda otomatik olarak gerçekleşmez.
Örnekte, tanıtım sıfırlamasının ardından şuna benzer bir şey görebilirsiniz:
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Sonuç kümesi aşağıdadır.
| MB cinsinden disk içi boyut |
|---|
| 11839 |
Yaklaşık 12 GB'da bu, demo sıfırlanmasından öncesinde sahip olduğumuz 9 GB'tan önemli ölçüde daha fazladır. Bunun nedeni, bazı denetim noktası dosya birleştirmelerinin başlatılmış olması, ancak birleştirme hedeflerinden bazılarının henüz yüklenmemiş olması ve aşağıdaki örnekte görüldüğü gibi birleştirme kaynak dosyalarından bazılarının henüz temizlenmemiş olmasıdır:
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;
Sonuç kümesi aşağıdadır.
state_desc |
file_type_desc |
count |
on-disk size MB |
|---|---|---|---|
| ÖNCEDEN OLUŞTURULMUŞ | VERİ | 16 | 2048 |
| ÖNCEDEN OLUŞTURULMUŞ | DELTA | 16 | 128 |
| ETKİN | VERİ | 38 | 5152 |
| ETKİN | DELTA | 38 | 1331 |
| HEDEFİ BİRLEŞTİr | VERİ | 7 | 896 |
| HEDEFİ BİRLEŞTİr | DELTA | 7 | 56 |
| BIRLEŞTIRILMIŞ KAYNAK | VERİ | 13 | 1772 |
| BIRLEŞTIRILMIŞ KAYNAK | DELTA | 13 | 455 |
Birleştirme hedefleri yüklenir ve sistemde işlem etkinliği gerçekleştiğinde birleştirilmiş kaynak temizlenir.
Tanıtım iş yükünü ikinci kez çalıştırdıktan ve iş yükü sıfırlandıktan sonra 10 milyon satış siparişi ekledikten sonra, iş yükünün ilk çalıştırması sırasında oluşturulan dosyaların temizlendiğini görürsünüz. İş yükü çalışırken önceki sorguyu birkaç kez çalıştırırsanız, denetim noktası dosyalarının çeşitli aşamalarda ilerleydiğini görebilirsiniz.
İş yükünün ikinci çalıştırmasında 10 milyon satış siparişi eklendikten sonra disk kullanımını çok benzer görürsünüz, ancak sistem doğası gereği dinamik olduğundan ilk çalıştırmadan sonra olduğu gibi olmayabilir. Mesela:
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;
Sonuç kümesi aşağıdadır.
state_desc |
file_type_desc |
count |
on-disk size MB |
|---|---|---|---|
| ÖNCEDEN OLUŞTURULMUŞ | VERİ | 16 | 2048 |
| ÖNCEDEN OLUŞTURULMUŞ | DELTA | 16 | 128 |
| YAPIM AŞAMASINDA | VERİ | 2 | 268 |
| YAPIM AŞAMASINDA | DELTA | 2 | 16 |
| ETKİN | VERİ | 41 | 5608 |
| ETKİN | DELTA | 41 | 328 |
Bu durumda UNDER CONSTRUCTION durumunda iki denetim noktası dosya çifti bulunmaktadır ve bu da, büyük olasılıkla iş yükündeki yüksek eşzamanlılık düzeyinden dolayı birden fazla dosya çiftinin UNDER CONSTRUCTION durumuna taşındığı anlamına gelir. Birden çok eşzamanlı iş parçacığı aynı anda yeni bir dosya çifti gerektirdi ve bu yüzden bir dosya çiftini PRECREATED'dan UNDER CONSTRUCTION'a taşıdı.
İlgili içerik
- Bellek İçi OLTP'ye genel bakış ve kullanım senaryoları
- Belleğe göre optimize edilmiş dosya grubu
- In-Memory OLTP'yi etkinleştirmek ve önerilen seçenekleri ayarlamak için Betiği