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ı
Azure SQL Yönetilen Örneği
Bellek için iyileştirilmiş tablolar, tüm satırları ve dizinleri bellekte tutmak için yeterli belleğin mevcut olmasını gerektirir. Bellek sınırlı bir kaynak olduğundan, sisteminizdeki bellek kullanımını anlamanız ve yönetmeniz önemlidir. Bu bölümdeki konular, yaygın bellek kullanımı ve yönetim senaryolarını kapsar.
Sunucuya yeterli bellek sağlayabilmeniz için bellek için iyileştirilmiş her tablonun bellek gereksinimlerini makul bir şekilde tahmin etmek önemlidir. Bu, hem yeni tablolar hem de disk tabanlı tablolardan geçirilen tablolar için geçerlidir. Bu bölümde, bellek için iyileştirilmiş bir tablo için verileri tutmak için gereken bellek miktarını tahmin etme işlemleri açıklanmaktadır.
Disk tabanlı tablolardan bellek için optimize edilmiş tablolara geçiş yapmayı düşünüyorsanız, hangi tabloların taşınması gerektiğine ilişkin rehberlik için Bir Tablo veya Saklı Yordamın In-Memory OLTP'ye Taşınıp Taşınmadığını Belirleme başlıklı rehbere bakın. OLTP'ye geçiş In-Memory altındaki tüm konular, disk tabanlı tablolardan bellek için iyileştirilmiş tablolara geçiş konusunda rehberlik sağlar.
Bellek Gereksinimlerini Tahmin Etmek için Temel Kılavuz
SQL Server 2016 (13.x) ve sonraki sürümlerinde, bellek için iyileştirilmiş tabloların boyutu için bir sınır yoktur, ancak tabloların belleğe sığmaları gerekir. SQL Server 2014'te (12.x), desteklenen veri boyutu SCHEMA_AND_DATA tablolar için 256 GB'tır.
Bellek için iyileştirilmiş bir tablonun boyutu, verilerin boyutuna ve satır üst bilgileri için ek yüke karşılık gelir. Bellek için iyileştirilmiş tablonun boyutu kabaca kümelenmiş dizinin veya özgün disk tabanlı tablonun yığınının boyutuna karşılık gelir.
Bellek için iyileştirilmiş tablolardaki dizinler, disk tabanlı tablolardaki kümelenmemiş dizinlerden daha küçük olma eğilimindedir. Kümelenmemiş dizinlerin boyutu [primary key size] * [row count]sırasına göredir. Hash indekslerin boyutu [bucket count] * 8 bytes.
Etkin bir iş yükü olduğunda, satır sürümü oluşturma ve çeşitli işlemleri hesaba eklemek için ek bellek gerekir. Gerekli bellek miktarı iş yüküne bağlıdır, ancak güvenli olmak için bellek için iyileştirilmiş tabloların ve dizinlerin beklenen boyutunun iki katıyla başlayıp gerçek bellek tüketimini gözlemlemeniz önerilir. Satır sürümü oluşturmanın yükü her zaman iş yükünün özelliklerine bağlıdır. Özellikle uzun süre çalışan işlemler ek yükü artırır. Daha büyük veritabanları kullanan çoğu iş yükünde (örneğin, 100 GB'tan büyük), ek yük sınırlı olma eğilimindedir (yüzde 25 veya daha az).
In-Memory OLTP altyapısındaki olası bellek yükü hakkında daha fazla bilgi için bkz. Bellek parçalanması.
Bellek Gereksinimlerinin Ayrıntılı Hesaplaması
tablo değişkenleri için bellek
Bellek için iyileştirilmiş örnek tablo
Bellek için iyileştirilmiş aşağıdaki tablo şemasını göz önünde bulundurun:
CREATE TABLE t_hk
(
col1 int NOT NULL PRIMARY KEY NONCLUSTERED,
col2 int NOT NULL INDEX t1c2_index
HASH WITH (bucket_count = 5000000),
col3 int NOT NULL INDEX t1c3_index
HASH WITH (bucket_count = 5000000),
col4 int NOT NULL INDEX t1c4_index
HASH WITH (bucket_count = 5000000),
col5 int NOT NULL INDEX t1c5_index NONCLUSTERED,
col6 char (50) NOT NULL,
col7 char (50) NOT NULL,
col8 char (30) NOT NULL,
col9 char (50) NOT NULL
) WITH (memory_optimized = on) ;
GO
Bu şemayı kullanarak bu bellek için iyileştirilmiş tablo için gereken en düşük belleği belirleyelim.
Tablo için bellek
Bellek için iyileştirilmiş bir tablo satırının üç bölümü vardır:
Zaman Damgaları
Satır üst bilgisi/zaman damgaları = 24 bayt.İndeks işaretçileri
Tablodaki her bir hash dizini için, her satırın dizindeki bir sonraki satıra işaret eden 8 baytlık bir adres işaretçisi vardır. Dört dizin olduğundan, her satır dizin işaretçileri için 32 bayt ayırır (her dizin için 8 baytlık bir işaretçi).veri
Satırın veri bölümünün boyutu, her veri sütunu için tür boyutu toplanarak belirlenir. Tablomuzda beş adet 4 baytlık tamsayı, üç adet 50 baytlık karakter sütunu ve bir adet 30 baytlık karakter sütunu vardır. Bu nedenle her satırın veri bölümü 4 + 4 + 4 + 4 + 4 + 50 + 50 + 30 + 50 veya 200 bayttır.
Aşağıda, bellek için iyileştirilmiş bir tablodaki 5.000.000 (5 milyon) satır için boyut hesaplaması yer alır. Veri satırları tarafından kullanılan toplam bellek aşağıdaki gibi tahmin edilir:
Tablonun satırları için bellek
Yukarıdaki hesaplamalardan, bellek için iyileştirilmiş tablodaki her satırın boyutu 24 + 32 + 200 veya 256 bayttır. 5 milyon satırımız olduğundan, tablo 5.000.000 * 256 bayt veya 1.280.000.000 bayt tüketir - yaklaşık 1,28 GB.
Dizinler için bellek
Her bir hash dizini için bellek
Her karma dizin, 8 baytlık adres işaretçilerinden oluşan bir karma dizisidir. Dizinin boyutu en iyi o dizin için benzersiz dizin değerlerinin sayısına göre belirlenir. Geçerli örnekte, benzersiz Col2 değerlerinin sayısı, t1c2_index dizi boyutu için iyi bir başlangıç noktasıdır. Fazla büyük bir karma dizisi bellek israf eder. Küçük boyutlu bir karma dizi, performansı düşürür çünkü aynı dizin girdisine sahip karma değerlerine göre çok fazla çakışma olur.
Karma dizinler aşağıdakiler gibi çok hızlı eşitlik aramaları elde eder:
SELECT * FROM t_hk
WHERE Col2 = 3;
Kümelenmemiş dizinler, şu aralık aramaları için daha hızlıdır:
SELECT * FROM t_hk
WHERE Col2 >= 3;
Disk tabanlı bir tabloyu geçiriyorsanız, dizin t1c2_index için benzersiz değerlerin sayısını belirlemek için aşağıdakileri kullanabilirsiniz.
SELECT COUNT(DISTINCT [Col2])
FROM t_hk;
Yeni bir tablo oluşturuyorsanız, dağıtımdan önce dizi boyutunu tahmin etmeniz veya testinizden veri toplamanız gerekir.
Karma dizinlerin OLTP bellek için iyileştirilmiş In-Memory tablolarda nasıl çalıştığı hakkında bilgi için bkz. Karma Dizinler.
Karma dizin dizisi boyutunu ayarlama
Karma dizi boyutu, (bucket_count= value) tarafından ayarlanır ve burada value sıfırdan büyük bir tamsayı değeridir.
value 2'nin gücü değilse, gerçek bucket_count 2'nin sonraki en yakın gücüne yuvarlanmış olur. Örnek tablomuzda (bucket_count = 5000000), 5.000.000 2'nin gücü olmadığından gerçek demet sayısı 8.388.608'e (2^23) kadar yuvarlanır. Karma dizi için gereken belleği hesaplarken 5.000.000 değil, bu sayıyı kullanmanız gerekir.
Bu nedenle, örneğimizde her karma dizi için gereken bellek şu şekildedir:
8.388.608 * 8 = 2^23 * 8 = 2^23 * 2^3 = 2^26 = 67.108.864 veya yaklaşık 64 MB.
Üç karma dizinimiz olduğundan karma dizinler için gereken bellek 3 * 64 MB = 192 MB'tır.
Kümelenmemiş dizinler için bellek
Kümelenmemiş dizinler, dizin değerini ve sonraki düğümlere yönelik işaretçileri içeren iç düğümlerle Bw ağaçları olarak uygulanır. Yaprak düğümler dizin değerini ve bellekteki tablo satırının işaretçisini içerir.
Karma dizinlerden farklı olarak, kümelenmemiş dizinlerin sabit demet boyutu yoktur. Dizin, verilerle birlikte dinamik olarak büyür ve küçülür.
Kümelenmemiş dizinler için gereken bellek aşağıdaki gibi hesaplanabilir:
Yaprak olmayan düğümlere ayrılan bellek
Tipik bir yapılandırma için, boş olmayan düğümlere ayrılan bellek, dizin tarafından alınan genel belleğin küçük bir yüzdesidir. Bu o kadar küçük ki, rahatlıkla göz ardı edilebilir.Yaprak düğümler için bellek
Yaprak düğümler, tablodaki her benzersiz anahtar için bu benzersiz anahtara sahip veri satırlarını gösteren bir satıra sahiptir. Aynı anahtara sahip birden çok satırınız varsa (başka bir deyişle, listelenmemiş bir dizininiz varsa), dizin yaprak düğümünde diğer satırların birbirine bağlı olduğu satırlardan birine işaret eden tek bir satır vardır. Bu nedenle, gereken toplam bellek yaklaşık olarak:- kümelenmemiş indeks için bellek = (işaretçi boyutu + toplam(anahtar sütun veri türü boyutları)) * benzersiz anahtarlı satırlar
Kümelenmemiş dizinler, aşağıdaki sorgu tarafından örneklendiği gibi, aralık aramaları için kullanıldığında en iyisidir:
SELECT * FROM t_hk
WHERE c2 > 5;
Satır versiyonlama için hafıza
kilitleri önlemek için, In-Memory OLTP satırları güncelleştirirken veya silerken iyimser eşzamanlılık kullanır. Bu, bir satır güncelleştirildiğinde satırın başka bir sürümünün oluşturulduğu anlamına gelir. Ayrıca, silmeler mantıksaldır; var olan satır silinmiş olarak işaretlenir, ancak hemen kaldırılmaz. Sistem, eski satır sürümlerini (silinen satırlar dahil) muhtemel sürümleri kullanabilecek tüm işlemler yürütmeyi tamamlayana kadar kullanılabilir durumda tutar.
Bellekte herhangi bir zamanda çöp toplama döngüsünün belleklerini serbest bırakmasını bekleyen çok daha fazla satır olabileceğinden, bu diğer satırları barındırmak için yeterli belleğe sahip olmanız gerekir.
Ek satır sayısı, saniye başına en yüksek satır güncelleştirme ve silme sayısı hesaplanarak ve ardından en uzun işlemin aldığı saniye sayısıyla (en az 1) çarpılarak tahmin edilebilir.
Bu değer daha sonra satır boyutuyla çarpılarak satır sürümü oluşturma için ihtiyacınız olan bayt sayısını alır.
rowVersions = durationOfLongestTransactionInSeconds * peakNumberOfRowUpdatesOrDeletesPerSecond
Eski satırlar için bellek gereksinimleri, eski satırların sayısı bellek için iyileştirilmiş bir tablo satırının boyutuyla çarpılarak tahmin edilir. Daha fazla bilgi için bkz. Tablonun belleği.
memoryForRowVersions = rowVersions * rowSize
Tablo değişkenleri için bellek
Tablo değişkeni için kullanılan bellek yalnızca tablo değişkeni kapsamın dışına çıktığında serbest bırakılır. Bir tablo değişkeninden bir güncelleştirme kapsamında silinen satırlar da dahil olmak üzere silinen satırlar çöp toplamaya tabi değildir. Tablo değişkeni kapsam dışına çıkana kadar bellek serbest bırakılmaz.
Saklı yordam yerine büyük bir SQL toplu işleminde tanımlanan ve birçok işlemde kullanılan tablo değişkenleri büyük miktarda bellek tüketebilir. Bunlar çöp olarak toplanmadığından, bir tablo değişkenindeki silinen satırlar çok fazla bellek tüketebilir ve silinen satırları taramak için okuma işlemlerinin performansı düşürebilir.
Büyüme için bellek
Önceki hesaplamalar, şu anda mevcut olan tablo için bellek gereksinimlerinizi tahmin eder. Bu belleğe ek olarak, tablonun büyümesini tahmin etmeniz ve bu büyümeyi karşılamak için yeterli bellek sağlamanız gerekir. Örneğin, 10% büyüme bekliyorsanız tablonuz için gereken toplam belleği almak için önceki sonuçları 1,1'e kadar katlamalısınız.
Bellek parçalanması
Bellek ayırma çağrılarının yükünü önlemek ve performansı geliştirmek için, In-Memory OLTP altyapısı her zaman süper engeller olarak adlandırılan 64 KB blokları kullanarak SQL Server İşletim Sistemi'nden (SQLOS) bellek ister.
Her süper blok, yalnızca sizeclass olarak adlandırılan belirli bir boyut aralığında bellek ayırmaları içerir. Örneğin, A süper bloğunun 1-16 bayt boyut sınıfında bellek ayırmaları olabilirken, B süper bloğunun 17-32 bayt boyut sınıfında bellek ayırmaları olabilir vb. olabilir.
Varsayılan olarak, super bloklar mantıksal CPU tarafından da bölünür. Bu, her mantıksal CPU için sizeclass'a göre daha da bölünmüş ayrı bir süper blok kümesi olduğu anlamına gelir. Bu, farklı CPU'larda yürütülen istekler arasında bellek ayırma çekişmesini azaltır.
In-Memory OLTP altyapısı yeni bir bellek ayırma işlemi yaptığında, önce istenen sizeclass ve isteği işleyen CPU için mevcut bir süper blokta boş bellek bulmayı dener. Bu girişim başarılı olursa, belirli bir bellek tüketicisinin used_bytessys.dm_xtp_system_memory_consumers sütunundaki değer istenen bellek boyutuna göre artar, ancak sütundaki allocated_bytes değer aynı kalır.
Mevcut süper bloklarda boş bellek yoksa, yeni bir süper blok ayrılır ve istenen bellek boyutu kadar `used_bytes` değer artar, `allocated_bytes` sütunundaki değer ise 64 KB artar.
Zaman içinde, süper bloklardaki bellek ayrıldığından ve serbest bırakıldığından, In-Memory OLTP altyapısı tarafından kullanılan toplam bellek miktarı, kullanılan bellek miktarından önemli ölçüde daha fazla olabilir. Başka bir deyişle, bellek parçalanabilir.
Atık toplama kullanılan belleği azaltabilir, ancak yalnızca bir veya daha fazla süper blok boşalır ve serbest bırakılırsa ayrılan belleği azaltır. Bu, sys.sp_xtp_force_gc sistem saklı yordamı kullanılarak hem otomatik hem de zorlamalı çöp toplama için geçerlidir.
In-Memory OLTP altyapısı bellek parçalanması ve ayrılan bellek kullanımı beklenenden yüksek olursa, izleme bayrağı 9898'i etkinleştirebilirsiniz. Bu, süper blok bölümleme şemasını CPU başına olandan her NUMA düğümüne değiştirerek toplam süper blok sayısını ve yüksek bellek parçalanma olasılığını azaltır.
Bu iyileştirme, birçok mantıksal CPU'ya sahip büyük makineler için daha ilgilidir. Bu optimizasyonun bir ödünü, daha az süper bloktan kaynaklanan ve genel iş yükü aktarım hızını azaltabilecek bellek ayırma çekişmesindeki olası bir artıştır. İş yükü desenlerine bağlı olarak, NUMA başına bellek bölümlemesi kullanımındaki aktarım hızının azaltılması fark edilebilir veya olmayabilir.