Aracılığıyla paylaş


Memory-Optimized Tablolardaki Dizinler

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen Örneği

Satırları birbirine bağlayan dizinler olduğundan, bellek için iyileştirilmiş tüm tabloların en az bir dizini olmalıdır. Bellek için iyileştirilmiş bir tabloda, her dizin de bellek için iyileştirilmiştir. Bellek için iyileştirilmiş bir tablodaki bir dizinin disk tabanlı tablodaki geleneksel bir dizinden farklı olması için çeşitli yollar vardır:

  • Veri satırları sayfalarda depolanmaz, bu nedenle bir tablonun tüm sayfalarını almak için başvurulabilecek sayfa veya kapsam koleksiyonu, bölüm veya ayırma birimi yoktur. Kullanılabilir dizin türlerinden biri için dizin sayfaları kavramı vardır, ancak bunlar disk tabanlı tablolar için dizinlerden farklı şekilde depolanır. Bir sayfada geleneksel parçalanma türünü biriktirmezler, bu nedenle doldurma faktörleri yoktur.
  • Veri işleme sırasında bellek için iyileştirilmiş tablolardaki dizinlerde yapılan değişiklikler hiçbir zaman diske yazılır. Yalnızca veri satırları ve verilerde yapılan değişiklikler işlem günlüğüne yazılır.
  • Veritabanı yeniden çevrimiçi duruma getirildiğinde bellek için iyileştirilmiş dizinler yeniden oluşturulur.

Bellek için iyileştirilmiş tablolardaki tüm dizinler, veritabanı kurtarma sırasındaki dizin tanımlarına göre oluşturulur.

Dizin aşağıdakilerden biri olmalıdır:

  • Hash dizini
  • Bellek için iyileştirilmiş Kümelenmemiş dizin (B ağacının varsayılan iç yapısı anlamına gelir)

Karma dizinleri, Memory-Optimized Tablolariçin Karma Dizinleri'nde daha ayrıntılı olarak ele alınmaktadır.
Kümelenmemiş dizinleri, Memory-Optimized Tablolar
için Kümelenmemiş Dizin'de daha ayrıntılı olarak ele alınmaktadır.
Columnstore dizinleri başka bir makaleele alınmaktadır.

Bellek için iyileştirilmiş dizinlerin söz dizimi

Bellek için iyileştirilmiş bir tabloya ait her CREATE TABLE deyimi, açıkça bir İNDİS aracılığıyla veya örtülü olarak bir BİRİNCİL ANAHTAR veya BENZERSİZ kısıtlaması aracılığıyla bir dizin içermelidir.

Varsayılan DAYANIKLILIK = SCHEMA_AND_DATA olarak ilan edilmesi için, bellek için optimize edilmiş tablonun birincil anahtarı olmalıdır. Aşağıdaki CREATE TABLE deyimindeki PRIMARY KEY NONCLUSTERED yan tümcesi iki gereksinimi karşılar:

  • CREATE TABLE deyiminde bir dizinin en düşük gereksinimini karşılayacak bir dizin sağlar.

  • SCHEMA_AND_DATA yan tümcesi için gereken birincil anahtarı sağlar.

    CREATE TABLE SupportEvent  
    (  
        SupportEventId   int NOT NULL  
            PRIMARY KEY NONCLUSTERED,  
        ...  
    )  
        WITH (  
            MEMORY_OPTIMIZED = ON,  
            DURABILITY = SCHEMA_AND_DATA);  
    

Not

SQL Server 2014 (12.x) ve SQL Server 2016 (13.x) bellek için iyileştirilmiş tablo veya tablo türü başına 8 dizin sınırına sahiptir. SQL Server 2017 'den (14.x) başlayarak ve Azure SQL Veritabanı'nda bellek için iyileştirilmiş tablolara ve tablo türlerine özgü dizin sayısı sınırı yoktur.

Söz dizimi için kod örneği

Bu alt bölüm, bellek için optimize edilmiş bir tabloda çeşitli dizinler oluşturmaya yönelik söz dizimini gösteren bir Transact-SQL kod bloğu içerir. Kod aşağıdakileri gösterir:

  1. Bellek için iyileştirilmiş bir tablo oluşturun.

  2. İki dizin eklemek için ALTER TABLE deyimlerini kullanın.

  3. Birkaç veri satırı ekleyin.

    DROP TABLE IF EXISTS SupportEvent;  
    go  
    
    CREATE TABLE SupportEvent  
    (  
        SupportEventId   int               not null   identity(1,1)  
        PRIMARY KEY NONCLUSTERED,  
    
        StartDateTime        datetime2     not null,  
        CustomerName         nvarchar(16)  not null,  
        SupportEngineerName  nvarchar(16)      null,  
        Priority             int               null,  
        Description          nvarchar(64)      null  
    )  
        WITH (  
        MEMORY_OPTIMIZED = ON,  
        DURABILITY = SCHEMA_AND_DATA);  
    go  
    
        --------------------  
    
    ALTER TABLE SupportEvent  
        ADD CONSTRAINT constraintUnique_SDT_CN  
        UNIQUE NONCLUSTERED (StartDateTime DESC, CustomerName);  
    go  
    
    ALTER TABLE SupportEvent  
        ADD INDEX idx_hash_SupportEngineerName  
        HASH (SupportEngineerName) WITH (BUCKET_COUNT = 64);  -- Nonunique.  
    go  
    
        --------------------  
    
    INSERT INTO SupportEvent  
        (StartDateTime, CustomerName, SupportEngineerName, Priority, Description)  
        VALUES  
        ('2016-02-23 13:40:41:123', 'Abby', 'Zeke', 2, 'Display problem.'     ),  
        ('2016-02-24 13:40:41:323', 'Ben' , null  , 1, 'Cannot find help.'    ),  
        ('2016-02-25 13:40:41:523', 'Carl', 'Liz' , 2, 'Button is gray.'      ),  
        ('2016-02-26 13:40:41:723', 'Dave', 'Zeke', 2, 'Cannot unhide column.');  
    go 
    

Yinelenen dizin anahtarı değerleri

Dizin anahtarı için yinelenen değerler bellek için iyileştirilmiş tabloların performansını düşürebilir. Çoğu dizin okuma ve yazma işlemi için giriş zincirlerinden geçiş yapmak için sistemin yinelemeleri. Yinelenen girişler zinciri 100 girdiyi aştığında performans düşüşü ölçülebilir hale gelebilir.

Yinelenen karma değerler

Hash dizinler söz konusu olduğunda bu sorun daha görünür. Karma dizinler, aşağıdaki etmenlerden dolayı daha fazla etkilenir:

  • Karma dizinler için işlem başına daha düşük maliyet.
  • Büyük yinelenen zincirlerin karma çakışmalar zinciri ile etkileşimi.

Dizinde yinelemeyi azaltmak için aşağıdaki ayarlamaları deneyin:

  • Kümelenmemiş bir dizin kullanın.
  • Yinelenenlerin sayısını azaltmak için dizin anahtarının sonuna ek sütunlar ekleyin.
    • Örneğin, birincil anahtarda da bulunan sütunları ekleyebilirsiniz.

Karma çakışmaları hakkında daha fazla bilgi için bkz. Memory-Optimized Tablolar için Karma Dizinler.

Örnek iyileştirme

Dizininizdeki performans verimsizliği önlemeye yönelik bir örnek aşağıda verilmiştir.

CustomerIdüzerinde birincil anahtarı olan ve CustomerCategoryIDsütununda dizini olan bir Customers tablosu düşünün. Genellikle belirli bir kategoride çok sayıda müşteri olacaktır. Bu nedenle, dizinin belirli bir anahtarının içinde CustomerCategoryID için birçok yinelenen değer olacaktır.

Bu senaryoda, en iyi yöntem (CustomerCategoryID, CustomerId)üzerinde bir kümelenmemiş dizin kullanmaktır. Bu dizin, CustomerCategoryIDiçeren bir koşul kullanan sorgular için kullanılabilir, ancak dizin anahtarı yineleme içermez. Bu nedenle, dizin bakımındaki verimsizliklerin nedeni yinelenen CustomerCategoryID değerleri veya dizindeki ek sütun değildir.

Aşağıdaki sorgu,WideWorldImporters örnek veritabanında tablosundaki dizin için ortalama yinelenen dizin anahtarı değerlerini gösterir.

SELECT AVG(row_count) FROM
    (SELECT COUNT(*) AS row_count 
	    FROM Sales.Customers
	    GROUP BY CustomerCategoryID) a

Kendi tablonuz ve dizininiz için dizin anahtarı yinelemelerinin ortalama sayısını değerlendirmek için, Sales.Customers tablonuzun adıyla değiştirin ve CustomerCategoryID dizin anahtarı sütunlarının listesiyle değiştirin.

Her dizin türünün ne zaman kullanılacağını karşılaştırma

Hangi dizin türünün en iyi seçenek olduğunu belirli sorgularınızın doğası belirler.

Mevcut bir uygulamada bellek için iyileştirilmiş tablolar uygulanırken genel öneri, disk tabanlı tablolardaki geleneksel kümelenmiş ve kümelenmemiş dizinlerin özelliklerine daha yakın olduğundan, kümelenmemiş dizinlerle başlamaktır.

Kümelenmemiş dizin kullanımına yönelik öneriler

Kümelenmemiş dizinler, şu durumlarda karma dizine göre tercih edilir:

  • Sorguların indeksli sütunda bir ORDER BY yan tümcesi vardır.
  • Çok sütunlu dizinin yalnızca önde gelen sütunlarının test edildiği sorgular.
  • Sorgular, dizine alınan sütunu bir WHERE koşul ifadesi kullanarak test etmektedir:
    • Eşitsizlik: WHERE StatusCode != 'Done'
    • Değer aralığı taraması: WHERE Quantity >= 100

Aşağıdaki tüm SELECT'lerde, karma dizin yerine kümelenmemiş dizin tercih edilir:

SELECT CustomerName, Priority, Description 
FROM SupportEvent  
WHERE StartDateTime > DateAdd(day, -7, GetUtcDate());  

SELECT StartDateTime, CustomerName  
FROM SupportEvent  
ORDER BY StartDateTime DESC; -- ASC would cause a scan.

SELECT CustomerName  
FROM SupportEvent  
WHERE StartDateTime = '2016-02-26';  

Karma dizin kullanımına yönelik öneriler

Karma dizinleri öncelikle aralık taramaları için değil nokta aramalarında kullanılır.

Aşağıdaki örnekte olduğu gibi sorgular eşitlik koşullarını kullandığında ve WHERE yan tümcesi tüm dizin anahtarı sütunlarıyla eşlendiğinde karma dizin, kümelenmemiş bir dizine göre tercih edilir:

SELECT CustomerName 
FROM SupportEvent  
WHERE SupportEngineerName = 'Liz';

Çok sütunlu dizin

Çok sütunlu dizin, kümelenmemiş bir dizin veya karma dizin olabilir. Dizin sütunlarının sütun1 ve sütun2 olduğunu varsayalım. Aşağıdaki SELECT deyimi göz önüne alındığında, sorgu iyileştiricisi için yalnızca kümelenmemiş dizin yararlı olabilir:

SELECT col1, col3  
FROM MyTable_memop  
WHERE col1 = 'dn';  

Karma dizin, anahtarındaki sütunların her biri için bir eşitlik testi belirtmek için WHERE yan tümcesine ihtiyaç duyar. Aksi halde karma dizin sorgu iyileştiricisi için kullanışlı değildir.

WHERE yan tümcesi dizin anahtarında yalnızca ikinci sütunu belirtiyorsa, dizin türü de yararlı olmaz.

Dizin kullanım senaryolarını karşılaştırmak için özet tablosu

Aşağıdaki tabloda, farklı dizin türleri tarafından desteklenen tüm işlemler listelenmektedir. Evet, dizinin isteği verimli bir şekilde karşılayabileceği anlamına gelir ve Hayır, dizinin isteği verimli bir şekilde karşılayamayacağı anlamına gelir.

İşlem Bellek açısından optimize edilmiş
Hash
Bellek iyileştirilmiş
kümelenmemiş
Disk tabanlı,
(kümelenmemiş)
Dizin Taraması, tüm tablo satırlarını alın. Evet Evet Evet
Eşitlik koşullarına (=) göre dizin araması. Evet
(Tam anahtar gereklidir.)
Evet Evet
Eşitsizlik ve aralık koşullarında indeks araması
(>, <, <=, >=, BETWEEN).
Hayır
(Dizin taramasına neden olur.)
Evet 1 Evet
Satırları dizin tanımıyla eşleşen bir sıralama düzeninde alın. Hayır Evet Evet
Dizin tanımının tersiyle eşleşen bir sıralama düzeninde satırları alın. Hayır Hayır Evet

1 Bellek için optimize edilmiş bir kümelenmemiş dizin için dizin araması gerçekleştirirken tam anahtar gerekli değildir.

Otomatik dizin ve istatistik yönetimi

Bir veya daha fazla veritabanının dizin birleştirme ve istatistik güncelleştirmelerini otomatik olarak yönetmek için Uyarlamalı Dizin Birleştirme gibi çözümlerden yararlanın. Bu yordam, diğer parametreler arasında bir dizini parçalanma düzeyine göre yeniden derlemeyi veya yeniden düzenlemeyi ve istatistikleri doğrusal bir eşikle güncelleştirmeyi otomatik olarak seçer.

Ayrıca Bkz.

sql server dizin tasarım kılavuzu
Memory-Optimized Tablolar
için Karma Dizinleri
Kümelenmemiş Dizinler Memory-Optimized Tablolar İçin
Uyarlamalı Dizin Birleştirme