Aracılığıyla paylaş


SQL Server ve Azure SQL dizin mimarisi ve tasarım kılavuzu

Şunlar için geçerlidir:SQL ServerAzure SQL VeritabanıAzure SQL Yönetilen ÖrneğiAzure Synapse AnalyticsAnalytics Platform Sistemi (PDW)Microsoft Fabric'teki SQL veritabanı

Kötü tasarlanmış dizinler ve dizin eksikliği, veritabanı uygulaması performans sorunlarının birincil kaynaklarıdır. Verimli dizinler tasarlamak, iyi veritabanı ve uygulama performansı elde etmek için çok önemlidir. Bu dizin tasarım kılavuzu, dizin mimarisi hakkında bilgiler ve uygulamanızın gereksinimlerini karşılayacak etkili dizinler tasarlamanıza yardımcı olacak en iyi yöntemleri içerir.

Bu kılavuz, okuyucunun kullanılabilir dizin türleri hakkında genel bir anlayışa sahip olduğunu varsayar. Dizin türlerinin genel açıklaması için bkz. Dizinler.

Bu kılavuz aşağıdaki dizin türlerini kapsar:

Birincil depolama biçimi Dizin türü
Disk tabanlı satır deposu
Kümelenmiş
Kümelenmemiş
Eşsiz
Filtre
Columnstore
Kümelenmiş columnstore
Kümelenmemiş sütun deposu
Bellek için iyileştirilmiş
Haş
Memory-Optimized kümesiz

XML dizinleri hakkında bilgi için bkz. XML dizinleri (SQL Server) ve Seçmeli XML dizinleri (SXI).

Uzamsal dizinler hakkında bilgi için bkz . Uzamsal Dizinlere Genel Bakış.

Tam metin dizinleri hakkında bilgi için bkz . Full-Text Dizinlerini Doldurma.

Dizin tasarımıyla ilgili temel bilgiler

Düzenli bir kitabı düşünün: Kitabın sonunda, kitap içinde bilgileri hızla bulmaya yardımcı olan bir dizin vardır. Dizin, anahtar sözcüklerin sıralanmış bir listesidir ve her anahtar sözcüğün yanında, her anahtar sözcüğün bulunabileceği sayfalara işaret eden sayfa numaraları kümesi bulunur.

Satır deposu dizini farklı değildir: sıralı bir değer listesidir ve her değer için bu değerlerin bulunduğu veri sayfalarının işaretçileri vardır. Dizinin kendisi, dizin sayfaları olarak adlandırılan sayfalarda depolanır. Normal bir kitapta, dizin birden çok sayfaya yayılmışsa ve örneğin sözcüğü SQL içeren tüm sayfaların işaretçilerini bulmanız gerekiyorsa, anahtar sözcüğünü SQLiçeren dizin sayfasını bulana kadar sayfayı kaydırmanız gerekir. Buradan, kitap sayfalarına götüren işaretleri takip edersiniz. Bu, dizinin en başında her harfin bulunabileceği alfabetik bir liste içeren tek bir sayfa oluşturursanız daha da iyileştirilebilir. Örneğin: "A - D - sayfa 121", "E - G - sayfa 122" vb. Bu ek sayfa, başlangıç noktasını bulmak için dizine göz atma adımını ortadan kaldırır. Böyle bir sayfa normal kitaplarda bulunmaz, ancak bir rowstore indeksinde vardır. Bu tek sayfa, dizinin kök sayfası olarak adlandırılır. Kök sayfa, dizin tarafından kullanılan ağaç yapısının başlangıç sayfasıdır. Ağaç benzetmesinin ardından, gerçek verilere yönelik işaretçiler içeren bitiş sayfaları, ağacın "yaprak sayfaları" olarak adlandırılır.

Dizin, tablo veya görünümden satırların alınmasını hızlandıran bir tablo veya görünümle ilişkili bir disk veya bellek içi yapıdır. Satır deposu dizini, tablo veya görünümdeki bir veya daha fazla sütundan oluşturulmuş anahtarlar içerir. Rowstore dizinleri için bu anahtarlar, Veritabanı Altyapısı'nın anahtar değerleriyle ilişkili satır veya satırları hızlı ve verimli bir şekilde bulmasını sağlayan bir ağaç yapısında (B+ ağaç) depolanır.

Satır deposu dizini, verileri mantıksal olarak satırlar ve sütunlar içeren bir tablo olarak düzenlenmiş ve fiziksel olarak satır deposu1 adlı satır tabanlı veri biçiminde veya columnstore adlı sütuna göre veri biçiminde depolanmış olarak depolar.

Veritabanı ve iş yükü için doğru dizinlerin seçilmesi, sorgu hızı ile güncelleştirme maliyeti arasında karmaşık bir dengeleme eylemidir. Dar disk tabanlı satır deposu dizinleri veya dizin anahtarında birkaç sütun bulunan dizinler, daha az disk alanı ve bakım yükü gerektirir. Öte yandan geniş dizinler daha fazla sorguyu kapsar. En verimli dizini bulmadan önce birkaç farklı tasarımla denemeniz gerekebilir. Dizinler veritabanı şemasını veya uygulama tasarımını etkilemeden eklenebilir, değiştirilebilir ve bırakılabilir. Bu nedenle, farklı dizinlerle deneme yapmaktan çekinmeyin.

Veritabanı Altyapısı'ndaki sorgu iyileştiricisi çoğu durumda en etkili dizini güvenilir bir şekilde seçer. Genel dizin tasarım stratejiniz, sorgu iyileştiricisinin doğru kararı vermesi için aralarından seçim yapması ve ona güvenmesi için çeşitli dizinler sağlamalıdır. Bu, analiz süresini azaltır ve çeşitli durumlarda iyi performans sağlar. Sorgu iyileştiricinin belirli bir sorgu için hangi dizinleri kullandığını görmek için SQL Server Management Studio'da Sorgu menüsünde Gerçek Yürütme Planını Ekle'yi seçin.

Dizin kullanımını her zaman iyi performansla, ve iyi performansı verimli dizin kullanımıyla eşitlemeyin. Dizin kullanmak her zaman en iyi performansın üretilmesine yardımcı olsaydı, sorgu iyileştiricisinin işi basit olurdu. Gerçekte, yanlış bir dizin seçimi en iyi performanstan daha az performansa neden olabilir. Bu nedenle, sorgu iyileştiricisinin görevi, yalnızca performansı geliştirdiğinde bir dizin veya dizin birleşimi seçmek ve performansı engellediği durumlarda dizinli aramalardan kaçınmaktır.

1 Rowstore, ilişkisel tablo verilerini depolamanın geleneksel yoludur. Rowstore , temel alınan veri depolama biçiminin bir yığın, B+ ağacı (kümelenmiş dizin) veya bellek için iyileştirilmiş bir tablo olduğu tabloyu ifade eder. Disk tabanlı satır deposu bellek için iyileştirilmiş tabloları dışlar.

Dizin tasarım görevleri

Aşağıdaki görevler dizinleri tasarlamak için önerilen stratejimizi oluşturur:

  1. Veritabanının özelliklerini anlayın.

  2. En sık kullanılan sorguların özelliklerini anlama. Örneğin, sık kullanılan bir sorgunun iki veya daha fazla tabloyu birleştirdiğini bilmek, kullanılacak en iyi dizin türünü belirlemenize yardımcı olur.

  3. Sorgularda kullanılan sütunların özelliklerini anlayın. Örneğin dizin, tamsayı veri türüne sahip olan ve aynı zamanda benzersiz veya null olmayan sütunlar için idealdir. İyi tanımlanmış veri alt kümeleri olan sütunlar için, SQL Server 2008 (10.0.x) ve üzeri sürümlerde filtrelenmiş dizin kullanabilirsiniz. Daha fazla bilgi için bu kılavuzdaki Filtrelenmiş dizin tasarımı yönergelerine bakın.

  4. Dizin oluşturulduğunda veya korunduğunda performansı geliştirebilecek dizin seçeneklerini belirleyin. Örneğin, mevcut büyük bir tabloda kümelenmiş bir dizin oluşturmak mevcut ONLINE dizin seçeneğinden yararlanabilir. seçeneği ONLINE , dizin oluşturulurken veya yeniden oluşturulurken temel alınan verilerde eşzamanlı etkinliğin devam etmesini sağlar. Daha fazla bilgi için bkz. Dizin Seçeneklerini Ayarlama.

  5. Dizin için en uygun depolama konumunu belirleyin.

    Kümelenmemiş dizin, temel alınan tabloyla aynı dosya grubunda veya farklı bir dosya grubunda depolanabilir. Dizinlerin depolama konumu, disk G/Ç performansını artırarak sorgu performansını geliştirebilir. Örneğin, kümelenmemiş dizini tablo dosya grubundan farklı bir diskte bulunan bir dosya grubunda depolamak, aynı anda birden çok disk okunabildiğinden performansı artırabilir. Alternatif olarak, kümelenmiş ve kümelenmemiş dizinler birden çok dosya grubu arasında bir bölüm düzeni kullanabilir. Bölümlemeyi düşündüğünüzde, dizinin tabloda olduğu gibi mi yoksa bağımsız şekilde mi bölümleneceğini belirleyin. Bu makalenin dosya gruplarında veya bölüm şemalarında dizin yerleşimi bölümünde daha fazla bilgi edinin.

  6. sys.dm_db_missing_index_details vesys.dm_db_missing_index_columns gibi Dinamik Yönetim Görünümleri (DMV) ile eksik dizinleri tanımladığınızda, aynı tablo ve sütunlarda benzer dizin çeşitlemeleri önerilebilir. Yinelenen dizinlerin oluşturulmasını önlemek için eksik dizin önerileriyle birlikte tablodaki mevcut dizinleri inceleyin. Eksik dizin önerileriyle kümelenmemiş dizinleri ayarlama konusunda daha fazla bilgi edinin.

Genel dizin tasarımı yönergeleri

Deneyimli veritabanı yöneticileri iyi bir dizin kümesi tasarlayabilir, ancak bu görev orta düzeyde karmaşık veritabanları ve iş yükleri için bile karmaşık, zaman alan ve hataya açık bir görevdir. Veritabanınızın, sorgularınızın ve veri sütunlarınızın özelliklerini anlamak, en uygun dizinleri tasarlamanıza yardımcı olabilir.

Veritabanında dikkat edilmesi gerekenler

Bir dizin tasarlarken aşağıdaki veritabanı yönergelerini göz önünde bulundurun:

  • Bir tablodaki çok sayıda dizin , , INSERTUPDATEve DELETE deyimlerinin MERGEperformansını etkiler çünkü tablodaki veriler değiştikçe tüm dizinlerin uygun şekilde ayarlanması gerekir. Örneğin, bir sütun birkaç dizinde kullanılırsa ve bu sütunun verilerini değiştiren bir UPDATE deyim yürütürseniz, bu sütunu içeren her dizin, temel alınan temel tablodaki (yığın veya kümelenmiş dizin) sütunun yanı sıra güncelleştirilmelidir.

    • Aşırı güncelleştirilmiş tabloları dizinlemekten kaçının ve dizinleri olabildiğince az sütunla dar tutun.

    • Düşük güncelleştirme gereksinimleri olan ancak büyük hacimli verileri olan tablolarda sorgu performansını geliştirmek için birçok dizin kullanın. Çok sayıda dizin, deyimler gibi SELECT verileri değiştirmeyen sorguların performansına yardımcı olabilir çünkü sorgu iyileştiricisinin en hızlı erişim yöntemini belirlemek için aralarından seçim yapabileceğiniz daha fazla dizin vardır.

  • Küçük tabloların dizine alınması en iyi yöntem olmayabilir çünkü sorgu optimizasyonunun veri aramak için dizini taraması, basit bir tablo taraması yapmasından daha uzun sürebilir. Bu nedenle, küçük tablolardaki dizinler hiçbir zaman kullanılmayabilir, ancak tablodaki veriler değiştikçe korunmalıdır.

  • Görünümdeki dizinler kümelemler, tablo birleştirmeleri veya kümelemler ve birleştirmelerin birleşimi içerdiğinde önemli performans kazançları sağlayabilir. Sorgu iyileştiricisinin bunu kullanması için sorguda görünüme açıkça başvurulması gerekmez.

  • Azure SQL Veritabanı'ndaki birincil çoğaltmalardaki veritabanları, dizinler için otomatik olarak veritabanı danışmanı performans önerileri oluşturur. İsteğe bağlı olarak otomatik dizin ayarlamayı etkinleştirebilirsiniz.

  • Sorgu Deposu, düşük performanslı sorguların tanımlanmasına yardımcı olur ve iyileştirici tarafından belirlenen veritabanı dizinlerini belgeleyen sorgu yürütme planlarının geçmişini sağlar.

Sorguyla ilgili dikkat edilmesi gerekenler

Bir dizin tasarlarken aşağıdaki sorgu yönergelerini göz önünde bulundurun:

  • Sorgulardaki koşul ve birleştirme koşullarında sık kullanılan sütunlarda kümelenmemiş dizinler oluşturun. Bunlar SARGable1 sütunlarınızdır. Ancak gereksiz sütunlar eklemekten kaçınmanız gerekir. Çok fazla dizin sütunu eklemek disk alanını ve dizin bakım performansını olumsuz etkileyebilir.

  • Sorgunun gereksinimlerini karşılamak için gereken tüm veriler dizinin içinde bulunduğundan, dizinleri kapsamak sorgu performansını geliştirebilir. Başka bir ifadeyle, istenen verileri almak için tablonun veya kümelenmiş dizinin veri sayfalarına değil, yalnızca dizin sayfalarına ihtiyaç vardır; bu da genel disk G/Ç'yi azaltır. Örneğin, A, B ve A sütunlarında oluşturulmuş bileşik bir dizine sahip olan bir tabloda, B ve C sütunlarını içeren bir sorgu, belirtilen verileri yalnızca dizinden alabilir.

    Kapsayan dizinler, temel tablosuna erişim olmadan ve aramalara neden olmadan bir veya birkaç benzer sorgu sonucunu doğrudan çözümleyen, kümelenmemiş bir dizinin atamasıdır.

    Bu tür dizinler, yaprak seviyesinde gerekli tüm SARGable olmayan sütunlara sahiptir. Bu, SELECT yan tümcesi ile tüm WHERE ve JOIN bağımsız değişkenleri tarafından döndürülen sütunların dizin tarafından kapsandığı anlamına gelir.

    Dizin, tablodaki satır ve sütunlara kıyasla yeterince dar olduğunda, sorgunun yürütülmesi için potansiyel olarak çok daha az giriş/çıkış işlemi yapılması gerekebilir. Bu da dizinin toplam sütunların gerçekten bir alt kümesi olduğu anlamına gelir.

    Büyük bir tablonun küçük bir bölümünü seçerken ve bu küçük bölümü sabit bir koşul, örneğin yalnızca birkaç null olmayan değer içeren seyrek sütunlar tanımladığında, dizinleri kapsayan seçenekleri göz önünde bulundurun.

  • Aynı satırları güncelleştirmek için birden çok sorgu kullanmak yerine, tek bir deyimde mümkün olduğunca çok satır ekleyen veya değiştiren sorgular yazın. Yalnızca bir deyim kullanılarak iyileştirilmiş dizin bakımdan yararlanılabilir.

  • Sorgu türünü ve sütunların sorguda nasıl kullanıldığını değerlendirin. Örneğin, tam eşleşme sorgu türünde kullanılan bir sütun, kümelenmemiş veya kümelenmiş dizin için iyi bir aday olabilir.

1 İlişkisel veritabanlarında SARGable terimi, sorgunun yürütülmesini hızlandırmak için bir dizin kullanabilen bir arama argümanı (Search ARGument) önermesini ifade eder.

Sütunla ilgili dikkat edilmesi gerekenler

Bir dizin tasarlarken aşağıdaki sütun yönergelerini göz önünde bulundurun:

  • Kümelenmiş dizinler için dizin anahtarının uzunluğunu kısa tutun. Ayrıca, kümelenmiş dizinler, benzersiz veya null olmayan sütunlarda oluşturulduğunda avantaj sağlar.

  • ntext, text, image, varchar(max), nvarchar(max)ve varbinary(max) veri türlerinden oluşan sütunlar dizin anahtarı sütunları olarak belirtilmez. Ancak , varchar(max), nvarchar(max), varbinary(max)ve xml veri türleri, anahtar olmayan dizin sütunları olarak bir kümelenmemiş dizine katılabilir. Daha fazla bilgi için bu kılavuzda yer alan sütunlarla dizin oluşturma bölümüne bakın.

  • Xml veri türü yalnızca XML dizinindeki bir anahtar sütun olabilir. Daha fazla bilgi için bkz. XML dizinleri (SQL Server). SQL Server 2012 SP1, Seçmeli XML Dizini olarak bilinen yeni bir XML dizini türü kullanıma sunulmuştur. Bu yeni dizin, XML olarak depolanan veriler üzerinde sorgu performansını iyileştirebilir, büyük XML veri iş yüklerinin daha hızlı dizinlenmesine olanak sağlayabilir ve dizinin depolama maliyetlerini azaltarak ölçeklenebilirliği artırabilir. Daha fazla bilgi için bkz . Seçmeli XML dizinleri (SXI).

  • Sütun benzersizliğini inceleyin. Aynı sütun kombinasyonunda benzersiz bir dizin yerine, benzersiz olmayan bir dizin sorgu iyileştiricisine dizini daha kullanışlı hale getiren ek bilgiler sağlar. Daha fazla bilgi için bu kılavuzdaki Benzersiz dizin tasarımı yönergelerine bakın.

  • Sütundaki veri dağıtımını inceleyin. Uzun süre çalışan bir sorguya genellikle birkaç benzersiz değere sahip bir sütunun dizinlenmesi veya bu tür bir sütun üzerinde birleştirme işlemi sebep olur. Bu, veri ve sorguyla ilgili temel bir sorundur ve genellikle bu durum tanımlanmadan çözülemez. Örneğin, aile adına göre alfabetik olarak sıralanmış bir fiziksel telefon dizini, şehirdeki tüm kişilerin adı Smith veya Jones ise bir kişiyi bulma işlemini hızlandırmaz. Veri dağıtımı hakkında daha fazla bilgi için bkz. İstatistikler.

  • Seyrek sütun, çoğunlukla NULL değer içeren sütunlar, değer kategorilerine sahip sütunlar ve farklı değer aralıklarına sahip sütunlar gibi iyi tanımlanmış alt kümelere sahip sütunlarda filtrelenmiş dizinler kullanmayı göz önünde bulundurun. İyi tasarlanmış bir filtrelenmiş dizin sorgu performansını artırabilir, dizin bakım maliyetlerini azaltabilir ve depolama maliyetlerini azaltabilir.

  • Dizinde birden çok sütun varsa sütunların sırasını göz önünde bulundurun. Yan tümcesinde eşittir (WHERE), büyüktür (=), küçüktür (>) veya < arama koşulunda kullanılan ya da birleştirmelerde (BETWEEN) katılan sütun önce yerleştirilmelidir. Ek sütunlar, en farklı olandan en az ayrılığa kadar olan benzersizlik düzeylerine göre sıralanmalıdır.

    Örneğin, dizin olarak LastNameFirstNametanımlanırsa, dizin, arama ölçütü WHERE LastName = 'Smith' veya WHERE LastName = Smith AND FirstName LIKE 'J%'olduğunda yararlıdır. Ancak, sorgu iyileştiricisi yalnızca üzerinde FirstName (WHERE FirstName = 'Jane')arama yapılan bir sorgu için dizini kullanmaz.

  • Hesaplanan sütunları dizine almayı göz önünde bulundurun. Daha fazla bilgi için bkz. Hesaplanan sütunlardaki dizinler.

Dizin özellikleri

Bir dizinin sorgu için uygun olduğunu belirledikten sonra, durumunuz için en uygun dizin türünü seçebilirsiniz. Dizin özellikleri aşağıdaki listeyi içerir:

  • Kümelenmiş ve kümelenmemiş
  • Benzersiz ve benzersiz olmayan karşılaştırması
  • Tek sütun ve çok sütunlu sütun karşılaştırması
  • Dizindeki sütunlarda artan veya azalan düzen
  • Tam tablo ve kümeli olmayan dizinler için filtrelenmiş karşılaştırması
  • Columnstore ile rowstore karşılaştırması
  • Bellek için iyileştirilmiş tablolar için karma ve kümelenmemiş karşılaştırma

Ayrıca, gibi FILLFACTORbir seçenek ayarlayarak dizinin ilk depolama özelliklerini özelleştirerek performansını veya bakımını iyileştirebilirsiniz. Ayrıca, performansı iyileştirmek için dosya gruplarını veya bölüm düzenlerini kullanarak dizin depolama konumunu belirleyebilirsiniz.

Dosya gruplarında veya bölüm düzenlerinde dizin yerleşimi

Dizin tasarım stratejinizi geliştirirken, dizinlerin veritabanıyla ilişkili dosya gruplarına yerleştirilmesini göz önünde bulundurmanız gerekir. Dosya grubunun veya bölüm düzeninin dikkatli bir şekilde seçilmesi sorgu performansını artırabilir.

Varsayılan olarak, dizinler dizinin oluşturulduğu temel tabloyla aynı dosya grubunda depolanır. Bölümlenmemiş kümelenmiş dizin ve temel tablo her zaman aynı dosya grubunda yer alır. Ancak aşağıdaki adımları uygulayabilirsiniz:

  • Temel tablonun veya kümelenmiş dizinin dosya grubu dışında bir dosya grubunda kümelenmemiş dizinler oluşturun.
  • Kümelenmiş ve kümelenmemiş dizinleri birden çok dosya grubuna yaymak için bölümleyin.
  • Kümelenmiş dizini düşürerek ve MOVE TO deyimindeki DROP INDEX yan tümcesinde yeni bir dosya grubu veya bölüm düzeni belirterek ya da CREATE INDEX deyimini DROP_EXISTING yan tümcesiyle kullanarak bir tabloyu bir dosya grubundan diğerine taşıyın.

Farklı bir dosya grubunda kümelenmemiş dizin oluşturarak, dosya grupları kendi denetleyicileriyle farklı fiziksel sürücüler kullanıyorsa performans artışları elde edebilirsiniz. Veri ve dizin bilgileri daha sonra birden çok disk kafası tarafından paralel olarak okunabilir. Örneğin, Table_A dosya grubunda ve f1 dosya grubunda Index_A her ikisi de aynı sorgu tarafından kullanılıyorsa, her iki dosya grubu da çekişme olmadan tam olarak kullanıldığından dolayı performans artışı elde edilebilir. Ancak, Table_A sorgu tarafından taranırsa ve Index_A başvurulmazsa, yalnızca dosya grubu f1 kullanılır. Bu, hiçbir performans kazancı oluşturmaz.

Ne tür bir erişimin gerçekleştiğini ve ne zaman gerçekleştiğini tahmin edemediğinizden, tablolarınızı ve dizinlerinizi tüm dosya gruplarına yaymak daha iyi bir karar olabilir. Bu, verilere hangi şekilde erişildiğine bakılmaksızın tüm veri ve dizinler tüm disklere eşit olarak yayıldığından tüm disklere erişildiğini garanti eder. Bu, sistem yöneticileri için de daha basit bir yaklaşımdır.

Birden çok dosya grubu arasında partisyonlar

Disk tabanlı kümelenmiş ve kümelenmemiş dizinleri birden çok dosya grubu arasında bölümleme de düşünebilirsiniz. Bölümlenmiş dizinler, bir bölüm işlevine göre yatay olarak veya satıra göre bölümlenir. partition işlevi, her satırın bölümleme sütunları olarak adlandırılan belirli sütunların değerlerine göre bir bölüm kümesine nasıl eşlenmiş olduğunu tanımlar. Bölüm düzeni, bölümlerin bir dosya grubu kümesine eşlemini belirtir.

Bir dizinin bölümlenmesi aşağıdaki avantajları sağlayabilir:

  • Büyük dizinleri daha yönetilebilir hale getiren ölçeklenebilir sistemler sağlayın. Örneğin OLTP sistemleri, büyük dizinlerle ilgilenen bölüme duyarlı uygulamalar uygulayabilir.

  • Sorguların daha hızlı ve daha verimli çalışmasını sağlayın. Sorgular bir dizinin birkaç bölümüne eriştiğinde, sorgu iyileştiricisi tek tek bölümleri aynı anda işleyebilir ve sorgudan etkilenmemiş bölümleri dışlayabilir.

Daha fazla bilgi için bkz . Bölümlenmiş tablolar ve dizinler.

Dizin sıralama düzeni tasarım yönergeleri

Dizinleri tanımlarken, dizin anahtarı sütununa ilişkin verilerin artan veya azalan sırada depolanması gerekip gerekmediğini göz önünde bulundurun. Artan varsayılandır ve Veritabanı Altyapısı'nın önceki sürümleriyle uyumluluğu korur. CREATE INDEX, CREATE TABLE ve ALTER TABLE ifadelerinin söz dizimi, dizinlerdeki ve kısıtlamalardaki tek tek sütunlarda ASC (artan) ve DESC (azalan) anahtar sözcüklerini destekler.

Tabloya ORDER BY başvuran sorgularda, söz konusu dizindeki anahtar sütunu veya sütunları için farklı yönler belirten yan tümceleri olduğunda, anahtar değerlerinin dizinde depolandığı sıranın belirtilmesi yararlı olur. Bu gibi durumlarda, dizin sorgu planındaki bir SORT işleç gereksinimini kaldırabilir; bu nedenle sorguyu daha verimli hale getirir. Örneğin Adventure Works Cycles satın alma departmanındaki alıcıların satıcılardan satın aldıkları ürünlerin kalitesini değerlendirmesi gerekir. Alıcılar en çok bu satıcılar tarafından gönderilen ürünleri yüksek ret oranıyla bulmakla ilgileniyorlar.

AdventureWorks örnek veritabanına yönelik aşağıdaki sorguda gösterildiği gibi, bu ölçütleri karşılayacak verilerin alınması için tablodaki sütunun RejectedQtyPurchasing.PurchaseOrderDetail azalan düzende (büyükten küçüke) sıralanması ve sütunun ProductID artan düzende (küçükten büyüğe) sıralanması gerekir.

SELECT RejectedQty,
       ((RejectedQty / OrderQty) * 100) AS RejectionRate,
       ProductID,
       DueDate
FROM Purchasing.PurchaseOrderDetail
ORDER BY RejectedQty DESC, ProductID ASC;
GO

Bu sorgudaki aşağıdaki yürütme planı, sorgu iyileştiricisinin SORT cümlede belirtilen sırayla sonuç kümesini döndürmek için bir ORDER BY işleç kullandığını gösterir.

Sorgu iyileştiricisinin, sonuç kümesini ORDER BY yan tümcesi tarafından belirtilen sırayla döndürmek için SORT işleci kullandığını gösteren bu sorgu için yürütme planının diyagramı.

Sorgudaki ORDER BY yan tümcesiyle eşleşen anahtar sütunlarla disk tabanlı bir satır deposu dizini oluşturulursa, sorgu planında SORT işleci ortadan kaldırılabilir ve böylece sorgu planı daha verimli hale gelir.

CREATE NONCLUSTERED INDEX IX_PurchaseOrderDetail_RejectedQty
ON Purchasing.PurchaseOrderDetail
    (RejectedQty DESC, ProductID ASC, DueDate, OrderQty);
GO

Sorgu yeniden yürütüldükten sonra, aşağıdaki yürütme planı işlecin ortadan kaldırıldığını ve yeni oluşturulan kümelenmemiş dizinin kullanıldığını gösterir SORT .

SIRALAMA işlecinin ortadan kaldırıldığını ve yeni oluşturulan kümelenmemiş dizinin kullanıldığını gösteren yürütme planının diyagramı.

Veritabanı Altyapısı her iki yönde de eşit derecede verimli bir şekilde hareket edebilir. olarak (RejectedQty DESC, ProductID ASC) tanımlanan bir dizin, yan tümcedeki sütunların ORDER BY sıralama yönünün ters çevrildiği bir sorgu için kullanılabilir. Örneğin, ORDER BY yan tümcesi ORDER BY RejectedQty ASC, ProductID DESC içeren bir sorgu dizini kullanabilir.

Sıralama düzeni yalnızca dizindeki anahtar sütunlar için belirtilebilir. sys.index_columns katalog görünümü ve işlev, dizin sütununun INDEXKEY_PROPERTY artan veya azalan sırada depolanıp depolanmadığını bildirir.

AdventureWorks örnek veritabanındaki kod örnekleriyle birlikte takip ediyorsanız, aşağıdaki Transact-SQL ile IX_PurchaseOrderDetail_RejectedQty, silme işlemi gerçekleştirebilirsiniz:

DROP INDEX IX_PurchaseOrderDetail_RejectedQty
ON Purchasing.PurchaseOrderDetail;
GO

Meta veriler

Dizinlerin özniteliklerini görmek için bu meta veri görünümlerini kullanın. Bazı görünümlerde daha fazla mimari bilgi yer almaktadır.

columnstore dizinleri için tüm sütunlar meta verilerde dahil edilen sütunlar olarak depolanır. columnstore dizininde anahtar sütunlar yoktur.

Kümelenmiş dizin tasarım yönergeleri

Kümelenmiş dizinler, tablodaki veri satırlarını anahtar değerlerine göre sıralar ve depolar. Veri satırlarının kendileri tek bir düzende sıralanabilir çünkü tablo başına yalnızca bir kümelenmiş dizin olabilir. Birkaç özel durum dışında, her tablonun sütunda veya sütunlarda tanımlanan ve aşağıdakileri sunan bir kümelenmiş dizini olmalıdır:

  • Sık kullanılan sorgular için kullanılabilir.

  • Yüksek düzeyde benzersizlik sağlar.

    Uyarı

    Kısıtlama PRIMARY KEY oluşturduğunuzda, sütun veya sütunlarda benzersiz bir dizin otomatik olarak oluşturulur. Varsayılan olarak, bu dizin kümelenmiştir; ancak kısıtlamayı oluştururken kümelenmemiş bir dizin belirtebilirsiniz.

  • Aralık sorgularında kullanılabilir.

UNIQUE özelliği kullanılarak kümelenmiş bir dizin oluşturulmamışsa, Veritabanı Motoru tabloya otomatik olarak 4 baytlık bir benzersizleştirici sütunu ekler. Gerektiğinde, Veritabanı Altyapısı her anahtarı benzersiz hale getirmek için bir satıra otomatik olarak bir benzersizleştirici değeri ekler. Bu sütun ve değerleri dahili olarak kullanılır ve kullanıcılar tarafından görülemez veya erişemez.

Kümelenmiş dizin mimarisi

Rowstore dizinleri B+ ağaçları olarak düzenlenir. Dizin B+ ağacındaki her sayfaya dizin düğümü adı verilir. B+ ağacının en üst düğümüne kök düğüm adı verilir. Dizindeki alt düğümler yaprak düğümler olarak adlandırılır. Kök ve yaprak düğümler arasındaki dizin düzeyleri topluca ara düzeyler olarak bilinir. Kümelenmiş dizinde yaprak düğümler, temel tablonun veri sayfalarını barındırır. Kök ve ara düzey düğümleri, dizin satırlarını tutan dizin sayfaları içerir. Her dizin satırı, bir anahtar değeri ve B+ ağacındaki bir ara düzey sayfasına veya dizinin yaprak düzeyindeki bir veri satırına yönelik bir işaretçi içerir. Dizinin her düzeyindeki sayfalar, ikiye kat bağlantılı bir listede bağlantılıdır.

Kümelenmiş dizinlerin sys.partitions içinde bir satırı vardır ve index_id = 1 dizin tarafından kullanılan her bölüm için kullanılır. Varsayılan olarak, kümelenmiş bir dizin tek bir bölüme sahiptir. Kümelenmiş dizinde birden çok bölüm olduğunda, her bölümün ilgili bölüme ilişkin verileri içeren bir B+ ağaç yapısı vardır. Örneğin, kümelenmiş bir dizinin dört bölümü varsa, dört B+ ağaç yapısı vardır; her bölümde bir tane.

Kümelenmiş dizindeki veri türlerine bağlı olarak, her kümelenmiş dizin yapısında belirli bir bölüme ait verilerin depolandığı ve yönetileceği bir veya daha fazla ayırma birimi vardır. En azından her kümelenmiş dizinin bölüm başına bir IN_ROW_DATA ayırma birimi vardır. Kümelenmiş dizin, büyük nesne (LOB) sütunları içeriyorsa bölüm başına bir LOB_DATA ayırma birimine de sahiptir. Ayrıca, 8.060 bayt satır boyutu sınırını aşan değişken uzunlukta sütunlar içeriyorsa bölüm başına bir ROW_OVERFLOW_DATA ayırma birimi vardır.

Veri zincirindeki sayfalar ve içindeki satırlar, kümelenmiş dizin anahtarının değerine göre sıralanır. Tüm eklemeler, eklenen satırdaki anahtar değerinin var olan satırlar arasında sıralama sırasına sığdığı noktada yapılır.

Bu çizimde tek bir bölümlemedeki kümelenmiş dizinin yapısı gösterilmektedir.

Tek bir bölümde kümelenmiş dizinin yapısını gösteren diyagram.

Sorguyla ilgili dikkat edilmesi gerekenler

Kümelenmiş dizinler oluşturmadan önce verilerinize nasıl erişilir anlayın. Aşağıdakileri yapacak sorgular için kümelenmiş dizin kullanmayı göz önünde bulundurun:

  • BETWEEN, >, >=, < ve <= gibi işleçleri kullanarak bir dizi değer döndürün.

    Kümelenmiş dizin kullanılarak ilk değere sahip satır bulunduktan sonra, sonraki dizine alınmış değerlere sahip satırların fiziksel olarak bitişik olması garanti edilir. Örneğin, bir sorgu bir satış siparişi numarası aralığı arasındaki kayıtları alırsa, sütundaki SalesOrderNumber kümelenmiş dizin, başlangıç satış siparişi numarasını içeren satırı hızla bulabilir ve son satış siparişi numarasına ulaşılana kadar tablodaki ardışık satırların tümünü alabilir.

  • Büyük sonuç kümeleri döndürür.

  • Yan tümceleri kullanın JOIN ; genellikle bunlar yabancı anahtar sütunlarıdır.

  • ORDER BY veya GROUP BY yan tümcelerini kullanın.

    ORDER BY veya GROUP BY yan tümcesinde belirtilen sütunlarda bir dizin, satırlar zaten sıralandığı için Veritabanı Altyapısı'nın verileri sıralama gereksinimini ortadan kaldırabilir. Bu, sorgu performansını artırır.

Sütunla ilgili dikkat edilmesi gerekenler

Genellikle, kümelenmiş dizin anahtarını olabildiğince az sütunla tanımlamanız gerekir. Aşağıdaki özniteliklerden birine veya daha fazlasına sahip sütunları göz önünde bulundurun:

  • Benzersizdir veya birçok farklı değer içerir

    Örneğin, bir çalışan kimliği çalışanları benzersiz olarak tanımlar. Sütundaki kümelenmiş dizin veya EmployeeID kısıtlaması, çalışan kimliği numarasına göre çalışan bilgilerini arayan sorguların performansını artırır. Alternatif olarak, çalışan kayıtları bu şekilde sık sık gruplandırıldığından ve sorgulandığından ve bu sütunların birleşimi yine de yüksek düzeyde fark sağlayacağından, üzerinde kümelenmiş bir dizin oluşturulabilirLastNameFirstNameMiddleName.

    Tavsiye

    Farklı belirtilmezse, BİrİnCİl ANAHTAR kısıtlaması oluştururken Veritabanı Altyapısı bu kısıtlamayı desteklemek için kümelenmiş bir dizin oluşturur.

    benzersizliği bir olarak zorlamak için kullanılabilir, ancak verimli bir kümeleme anahtarı değildir.

    Bir benzersiz belirleyiciPRIMARY KEY olarak kullanılıyorsa, bunun kümelenmemiş bir dizin olarak oluşturulması ve kümelenmiş dizini oluşturmak için IDENTITY gibi başka bir sütunun kullanılması önerilir.

  • Sırayla erişilir

    Örneğin, bir ürün kimliği veritabanındaki tablodaki Production.ProductAdventureWorks2022 ürünleri benzersiz olarak tanımlar. WHERE ProductID BETWEEN 980 and 999 gibi sıralı arama belirtilen sorgular, ProductID üzerinde kümelenmiş bir dizinden faydalanabilir. Bunun nedeni satırların bu anahtar sütununda sıralı olarak depolanmasıdır.

  • olarak IDENTITYtanımlanır.

  • Bir tablodan alınan verileri sıralamak için sık kullanılır.

    Sütun her sorgulandığında sıralama işleminin maliyetinden tasarruf etmek için bu sütundaki tabloyu kümelendirmek (fiziksel olarak sıralamak) iyi bir fikir olabilir.

Kümelenmiş dizinler aşağıdaki öznitelikler için iyi bir seçim değildir:

  • Sık yapılan değişikliklerden geçen sütunlar

    Bu, Veritabanı Motoru'nun bir satırın veri değerlerini fiziksel sırada tutması gerektiği için, tüm satırın hareket etmesine neden olur. Bu, verilerin genellikle geçici olduğu yüksek hacimli işlem işlem sistemlerinde önemli bir noktadır.

  • Geniş tuşlar

    Geniş tuşlar, birkaç sütunun veya birkaç büyük boyutlu sütunun bileşimidir. Kümelenmiş dizindeki anahtar değerleri, tüm kümelenmemiş dizinler tarafından arama anahtarları olarak kullanılır. Kümelenmemiş dizin girdileri kümeleme anahtarını ve bu kümelenmemiş dizin için tanımlanan anahtar sütunlarını içerdiğinden, aynı tabloda tanımlanan tüm kümelenmemiş dizinler önemli ölçüde büyüktür.

Kümelenmemiş dizin tasarım yönergeleri

Disk tabanlı bir satır deposu kümelenmemiş dizini, tablo verilerinin depolama konumuna işaret eden dizin anahtarı değerlerini ve satır bulucularını içerir. Bir tabloda veya dizinli görünümde birden çok kümelenmemiş dizin oluşturabilirsiniz. Genellikle, kümelenmiş dizin kapsamında olmayan sık kullanılan sorguların performansını artırmak için kümelenmemiş dizinler tasarlanmalıdır.

Bir kitaptaki dizin kullanımınıza benzer şekilde, sorgu iyileştiricisi de tablodaki veri değerinin konumunu bulmak için kümelenmemiş dizinde arama yaparak veri değerini arar ve ardından verileri doğrudan bu konumdan alır. Bu, dizin sorgularda aranmakta olan veri değerlerinin tablosundaki tam konumu açıklayan girdiler içerdiğinden, kümelenmemiş dizinleri tam eşleşme sorguları için en uygun seçenek haline getirir. Belirli bir yöneticiye rapor veren tüm çalışanlar için HumanResources.Employee tablosunu sorgulamak amacıyla, sorgu iyileştiricisi IX_Employee_ManagerID kümelenmemiş dizini kullanabilir; bu durumda ManagerID, anahtar sütun olarak kullanılmaktadır. Sorgu iyileştirici, dizinde belirtilen ManagerIDile eşleşen tüm girişleri hızla bulabilir. Her dizin girişi, tablodaki tam sayfayı ve satırı veya ilgili verilerin bulunabileceği kümelenmiş dizini gösterir. Sorgu iyileştiricisi dizindeki tüm girişleri bulduklarından sonra, verileri almak için doğrudan tam sayfaya ve satıra gidebilir.

Kümelenmemiş dizin mimarisi

Disk tabanlı satır deposu kümelenmemiş dizinler, aşağıdaki önemli farklılıklar dışında kümelenmiş dizinler ile aynı B+ ağaç yapısına sahiptir:

  • Temel alınan tablonun veri satırları, kümelenmemiş anahtarlarına göre sıralanıp sırayla depolanmaz.

  • Kümelenmemiş dizinin yaprak düzeyi, veri sayfaları yerine dizin sayfalarından oluşur. Bir kümelenmemiş dizinin yaprak düzeyindeki dizin sayfaları, anahtar sütunları ve dahil edilen sütunları içerir.

Kümelenmemiş dizin satırlarındaki satır bulucuları, bir satırın işaretçisidir veya aşağıda açıklandığı gibi bir satır için kümelenmiş dizin anahtarıdır:

  • Tablo bir yığın ise, yani kümelenmiş dizini yoksa, satır konumlayıcı satıra işaret eden bir işaretçidir. İşaretçi, dosya tanımlayıcısından (KIMLIK), sayfa numarasından ve sayfadaki satırın sayısından oluşturulur. İşaretçinin bütünü Satır Kimliği (RID) olarak bilinir.

  • Tabloda kümelenmiş dizin varsa veya dizin dizinli bir görünümdeyse, satır bulucu satırın kümelenmiş dizin anahtarıdır.

Satır bulucuları, kümelenmemiş dizin satırları için benzersizlik de sağlar. Aşağıdaki tabloda Veritabanı Altyapısı'nın kümelenmemiş dizinlere nasıl satır bulucuları eklediği açıklanmaktadır:

Tablo türü Kümelenmemiş dizin türü Satır bulucu
Yığın
Özgün olmayan Anahtar sütunlara RID eklendi
Eşsiz Eklenen sütunlara RID eklendi
Benzersiz kümelenmiş dizin
Özgün olmayan Anahtar sütunlarına eklenen kümelenmiş dizin anahtarları
Eşsiz Dahil edilen sütunlara eklenen kümelenmiş dizin anahtarları
Benzersiz olmayan kümelenmiş dizin
Özgün olmayan Kümelenmiş dizin anahtarları ve benzersizleştirici (mevcutsa) anahtar sütunlarına eklenir.
Eşsiz Dahil edilen sütunlara, mevcut olduklarında, kümelenmiş dizin anahtarları ve benzersizleştiriciler eklendi.

Veritabanı Altyapısı hiçbir zaman belirli bir sütunu bir kümelenmemiş dizinde iki kez depolamaz. Kullanıcı, bir kümelenmemiş dizin oluştururken belirtilen dizin anahtarı sırası her zaman kabul edilir: kümelenmemiş bir dizinin anahtarına eklenmesi gereken tüm satır bulucu sütunları, dizin tanımında belirtilen sütunların ardından anahtarın sonuna eklenir. Kümelenmiş dizin anahtar tabanlı satır bulucu sütunları, dizin tanımında açıkça belirtilip belirtilmediklerine bakılmaksızın sorgu iyileştiricisi tarafından kullanılabilir.

Aşağıdaki örneklerde, satır bulucularının kümelenmemiş dizinlerde nasıl uygulandığı gösterilmektedir:

Kümelenmiş indeks Kümelenmemiş dizin tanımı Satır bulucuları olan kümelenmemiş dizin tanımı Açıklama
Anahtar sütunları (A, B, C) ile benzersiz kümelenmiş dizin Anahtar sütunları (B, A) ve dahil edilen sütunlar (E, G) ile tekil olmayan kümelenmemiş dizin Anahtar sütunları (B, A, C) ve dahil edilen sütunlar (E, G) Kümelenmemiş dizin nonunique olduğundan, satır bulucunun dizin anahtarlarında mevcut olması gerekir. Satır bulucudaki B ve A sütunları zaten mevcut, bu nedenle yalnızca c sütunu eklenir. Sütun c , anahtar sütun listesinin sonuna eklenir.
Anahtar sütunlu benzersiz kümelenmiş dizin (A) Benzer olmayan, kümelenmemiş dizin anahtar sütunları (B, C) ve dahil edilen sütun (A) ile Anahtar sütunları (B, C, A) Kümelenmemiş dizin nonunique olduğundan satır bulucu anahtara eklenir. Sütun A zaten anahtar sütun olarak belirtilmediğinden, anahtar sütun listesinin sonuna eklenir. Sütun A artık anahtarda olduğundan, sütunu dahil edilen bir sütun olarak depolamanız gerekmez.
Anahtar sütunlu benzersiz kümelenmiş dizin (A, B) Anahtar sütunlu benzersiz kümelenmemiş dizin (C) Anahtar sütunu (C) ve dahil edilen sütunlar (A, B) Kümelenmemiş dizin benzersizdir, bu nedenle satır bulucu dahil edilen sütunlara eklenir.

Kümelenmemiş dizinlerin sys.partitions içinde, dizin tarafından kullanılan her bölüm için bir index_id > 1 satırı vardır. Varsayılan olarak, kümelenmemiş bir dizinin tek bir bölümü vardır. Bir kümelenmemiş dizinin birden çok bölümü olduğunda, her bölümün ilgili bölüm için dizin satırlarını içeren bir B+ ağaç yapısı vardır. Örneğin, bir kümelenmemiş dizinin dört bölümü varsa, her bölümde bir tane olmak üzere dört B+ ağaç yapısı vardır.

Kümelenmemiş dizindeki veri türlerine bağlı olarak, her bir kümelenmemiş dizin yapısında belirli bir bölüme ait verilerin depolandığı ve yönetileceği bir veya daha fazla ayırma birimi vardır. En azından, her bir kümelenmemiş dizin, dizin B+ ağaç sayfalarını depolayan bölüm başına bir IN_ROW_DATA ayırma birimine sahiptir. Kümelenmemiş dizin, büyük nesne (LOB) sütunları içeriyorsa bölüm başına bir LOB_DATA ayırma birimine de sahiptir. Ayrıca, 8.060 bayt satır boyutu sınırını aşan değişken uzunlukta sütunlar içeriyorsa bölüm başına bir ROW_OVERFLOW_DATA ayırma birimi vardır.

Aşağıdaki çizimde, tek bir bölümdeki bir kümelenmemiş dizinin yapısı gösterilmektedir.

Tek bir bölümdeki kümelenmemiş dizinin yapısını gösteren diyagram.

Veritabanında dikkat edilmesi gerekenler

Kümelenmemiş dizinler tasarlarken veritabanının özelliklerini göz önünde bulundurun.

  • Düşük güncelleştirme gereksinimlerine sahip veritabanları veya tablolar, ancak sorgu performansını geliştirmek için çok büyük hacimli veriler birçok kümelenmemiş dizinden yararlanabilir. Sorgu performansını geliştirmek, dizin depolama maliyetlerini azaltmak ve tam tablodaki kümelenmemiş dizinlerle karşılaştırıldığında dizin bakım maliyetlerini azaltmak için iyi tanımlanmış veri alt kümeleri için filtrelenmiş dizinler oluşturmayı göz önünde bulundurun.

    Karar Destek Sistemi uygulamaları ve veritabanları öncelikli olarak salt okunur veriler içeren birçok kümelenmemiş dizinden yararlanabilir. Sorgu iyileştiricisi, en hızlı erişim yöntemini belirlemek için aralarından seçim yapabileceğiniz daha fazla dizine sahiptir ve veritabanının düşük güncelleştirme özellikleri dizin bakımının performansa engel olmadığı anlamına gelir.

  • Aşırı güncelleştirilmiş tablolar içeren Çevrimiçi İşlem İşleme (OLTP) uygulamaları ve veritabanları fazla dizin oluşturmayı önlemelidir. Buna ek olarak, dizinler mümkün olduğunca az sütun içeren dar olmalıdır.

    Bir tablodaki çok sayıda dizin , , INSERTUPDATEve DELETE deyimlerinin MERGEperformansını etkiler çünkü tablodaki veriler değiştikçe tüm dizinlerin uygun şekilde ayarlanması gerekir.

Sorguyla ilgili dikkat edilmesi gerekenler

Kümelenmemiş dizinler oluşturmadan önce verilerinize nasıl erişilir anlamanız gerekir. Aşağıdaki özniteliklere sahip sorgular için kümelenmemiş dizin kullanmayı göz önünde bulundurun:

  • JOIN veya GROUP BY yan tümcelerini kullanın.

    Birleştirme ve gruplandırma işlemlerinde yer alan sütunlarda birden çok kümelenmemiş dizin ve herhangi bir yabancı anahtar sütunlarında kümelenmiş dizin oluşturun.

  • Büyük sonuç kümeleri döndürmeyen sorgular.

    Büyük bir tablodan iyi tanımlanmış bir satır alt kümesi döndüren sorguları kapsayacak şekilde filtrelenmiş dizinler oluşturun.

    Tavsiye

    Genellikle bir WHERE ifadesinin CREATE INDEX yan tümcesi, üzerinde çalışılan sorgunun WHERE yan tümcesi ile eşleşir.

  • Sık sık bir sorgunun arama koşullarında yer alan ve tam eşleşmeleri döndüren WHERE gibi sütunları içerir.

    Tavsiye

    Yeni dizinler eklerken maliyeti ve avantajı göz önünde bulundurun. Ek sorgu gereksinimlerini mevcut bir dizinde birleştirmek tercih edilebilir. Örneğin, her kritik sorgu için tam olarak bir tane kapsayan dizine sahip olmak yerine, birkaç kritik sorgunun kapsamına olanak tanıyorsa, mevcut bir dizine bir veya iki ek yaprak düzeyi sütunu eklemeyi göz önünde bulundurabilirsiniz.

Sütunla ilgili dikkat edilmesi gerekenler

Şu özniteliklerden birine veya daha fazlasına sahip sütunları göz önünde bulundurun:

  • Sorguyu kapsar.

    Dizin sorgudaki tüm sütunları içerdiğinde performans kazançları elde edilir. Sorgu iyileştiricisi dizindeki tüm sütun değerlerini bulabilir; tablo veya kümelenmiş dizin verilerine erişilmezse disk G/Ç işlemleri daha az olur. Geniş bir dizin anahtarı oluşturmak yerine kapsayan sütunlar eklemek için dahil edilen sütunlarla dizin kullanın.

    Tabloda kümelenmiş dizin varsa, kümelenmiş dizinde tanımlanan sütun veya sütunlar tablodaki her bir kümelenmemiş dizine otomatik olarak eklenir. Bu, kümelenmiş dizin sütunlarını kümelenmemiş dizinin tanımında belirtmeden kapsanan bir sorgu oluşturabilir. Örneğin, bir tablonun C sütununda kümelenmiş bir dizin varsa, B ve A sütunlarında benzersiz olmayan kümelenmemiş bir dizin olur ve anahtar değer sütunları B, A ve C şeklindedir. Daha fazla bilgi için , kümelenmemiş dizin mimarisini ziyaret edin.

  • Diğer sütunlar için kümelenmiş dizin kullanılıyorsa, aile adı ve adın birleşimi gibi çok sayıda farklı değer olabilir.

    Yalnızca 1 ve 0gibi çok az farklı değer varsa, tablo taraması genellikle daha verimli olduğundan sorguların çoğu dizini kullanmaz. Bu tür veriler için, yalnızca birkaç satırda gerçekleşen ayrı bir değer üzerinde filtrelenmiş dizin oluşturmayı göz önünde bulundurun. Örneğin, değerlerin 0çoğu ise, sorgu iyileştiricisi içeren 1veri satırları için filtrelenmiş dizin kullanabilir.

Kümelenmemiş dizinleri genişletmek için dahil edilen sütunları kullanma

Anahtar olmayan sütunları, kümelenmemiş dizinin yaprak düzeyine ekleyerek, kümelenmemiş dizinlerin işlevselliğini genişletebilirsiniz. Anahtar olmayan sütunları ekleyerek, daha fazla sorgu kapsayan kümelenmemiş dizinler oluşturabilirsiniz. Bunun nedeni, anahtar olmayan sütunların aşağıdaki avantajlara sahip olmasıdır:

  • Bunlar dizin anahtarı sütunları olarak izin verilmeyen veri türleri olabilir.

  • Dizin anahtarı sütunlarının veya dizin anahtarı boyutunun sayısı hesaplanırken Veritabanı Altyapısı tarafından dikkate alınmaz.

Anahtar olmayan sütunları içeren bir dizin, sorgudaki tüm sütunlar anahtar veya anahtar olmayan sütunlar olarak dizine dahil edildiğinde sorgu performansını önemli ölçüde artırabilir. Sorgu iyileştiricisi dizindeki tüm sütun değerlerini bulabildiği için performans kazançları elde edilir; tablo veya kümelenmiş dizin verilerine erişilmezse disk G/Ç işlemleri daha az olur.

Uyarı

Bir dizin, sorgu tarafından başvuruda bulunılan tüm sütunları içerdiğinde genellikle sorguyu kapsayan olarak adlandırılır.

Anahtar sütunlar dizinin tüm düzeylerinde depolanırken, anahtar olmayan sütunlar yalnızca yaprak düzeyinde depolanır.

Boyut sınırlarını önlemek için dahil edilen sütunları kullanma

En fazla 16 anahtar sütunu ve en fazla 900 bayt dizin anahtarı boyutu olan geçerli dizin boyutu sınırlamalarını aşmamak için, kümelenmemiş dizine anahtar olmayan sütunlar ekleyebilirsiniz. Veritabanı Altyapısı, dizin anahtarı sütunlarının veya dizin anahtarı boyutunun sayısını hesaplarken anahtar olmayan sütunları dikkate almaz.

Örneğin, tabloda aşağıdaki sütunları Document dizine almak istediğinizi varsayalım:

Title NVARCHAR(50)
Revision NCHAR(5)
FileName NVARCHAR(400)

nchar ve nvarchar veri türleri her karakter için 2 bayt gerektirdiğinden, bu üç sütunu içeren bir dizin 900 bayt boyut sınırlamasını 10 bayt (455 * 2) aşacak. deyiminin INCLUDE yan tümcesi CREATE INDEX kullanılarak dizin anahtarı (Title, Revision) ve FileName anahtar olmayan sütun olarak tanımlanabilir. Bu şekilde dizin anahtarı boyutu 110 bayt (55 * 2) olur ve dizin yine de tüm gerekli sütunları içerir. Aşağıdaki deyim böyle bir dizin oluşturur.

CREATE INDEX IX_Document_Title
ON Production.Document(Title, Revision)
    INCLUDE(FileName);
GO

Kod örneklerini takip ediyorsanız bu Transact-SQL deyimini kullanarak bu dizini silebilirsiniz.

DROP INDEX IX_Document_Title
ON Production.Document;
GO

Eklenen sütunları içeren dizinler için yönergeler

Dahil edilen sütunlarla kümelenmemiş dizinler tasarlarken aşağıdaki yönergeleri göz önünde bulundurun:

  • Anahtar olmayan sütunlar INCLUDE ifadesinin CREATE INDEX cümlesinde tanımlanır.

  • Anahtar olmayan sütunlar yalnızca tablolarda veya dizinlenmiş görünümlerde kümelenmemiş dizinlerde tanımlanabilir.

  • metin, ntextve resimdışında tüm veri türlerine izin verilir.

  • Belirleyici ve kesin veya kesin olmayan hesaplanan sütunlar dahil edilebilir. Daha fazla bilgi için bkz. Hesaplanan sütunlardaki dizinler.

  • Anahtar sütunlarda olduğu gibi, görüntü, ntext ve metin veri türlerinden türetilen hesaplanan sütunlar, hesaplanmış sütun veri türüne anahtar olmayan dizin sütunu olarak izin verildiğinde anahtar olmayan (dahil) sütunlar olabilir.

  • Sütun adları hem listede hem de INCLUDE anahtar sütun listesinde belirtilemiyor.

  • Sütun adları listede yinelenemez INCLUDE .

Sütun boyutu yönergeleri

  • En az bir anahtar sütunu tanımlanmalıdır. Anahtar olmayan sütun sayısı üst sınırı 1.023 sütundur. Bu, en fazla tablo sütunu sayısı eksi 1'dir.

  • Anahtar olmayanlar hariç dizin anahtarı sütunları, en fazla 16 anahtar sütunu ve toplam dizin anahtarı boyutu 900 bayt olan mevcut dizin boyutu kısıtlamalarını izlemelidir.

  • Tüm anahtar olmayan sütunların toplam boyutu yalnızca yan tümcesinde INCLUDE belirtilen sütunların boyutuyla sınırlıdır; örneğin , varchar(max) sütunları 2 GB ile sınırlıdır.

Sütun değiştirme yönergeleri

Eklenen sütun olarak tanımlanmış bir tablo sütununu değiştirdiğinizde, aşağıdaki kısıtlamalar uygulanır:

  • İlk olarak dizin bırakılmadığı sürece, anahtar olmayan sütunlar tablodan bırakılamaz.

  • Aşağıdakiler dışında, anahtar olmayan sütunlar değiştirilemez:

    • sütunun NOT NULLNULLnull atanabilirliğini olarak değiştirin.

    • Varchar, nvarchar veya varbinary sütunlarının uzunluğunu artırın.

      Uyarı

      Bu sütun değişikliği kısıtlamaları dizin anahtarı sütunları için de geçerlidir.

Tasarım önerileri

Yalnızca arama ve aramalar için kullanılan sütunların anahtar sütunlar olması için büyük bir dizin anahtarı boyutuyla kümelenmemiş dizinleri yeniden tasarlayın. Sorguyu kapsayan diğer tüm sütunları anahtar olmayan sütunlara dahil edin. Bu şekilde, sorguyu kapsamak için gereken tüm sütunlara sahip olursunuz, ancak dizin anahtarının kendisi küçük ve verimlidir.

Örneğin, aşağıdaki sorguyu kapsayacak şekilde bir dizin tasarlamak istediğinizi varsayalım.

SELECT AddressLine1,
       AddressLine2,
       City,
       StateProvinceID,
       PostalCode
FROM Person.Address
WHERE PostalCode BETWEEN N'98000' AND N'99999';
GO

Sorguyu kapsamak için her sütunun dizinde tanımlanması gerekir. Tüm sütunları anahtar sütunları olarak tanımlayabilseniz de, anahtar boyutu 334 bayt olabilir. Arama ölçütü olarak kullanılan tek sütun, uzunluğu 30 bayt olan sütun olduğundan PostalCode , daha iyi bir dizin tasarımı anahtar sütun olarak tanımlar PostalCode ve diğer tüm sütunları anahtar olmayan sütunlar olarak ekler.

Aşağıdaki deyim, sorguyu kapsayacak şekilde eklenen sütunlar içeren bir dizin oluşturur.

CREATE INDEX IX_Address_PostalCode
ON Person.Address(PostalCode)
    INCLUDE(AddressLine1, AddressLine2, City, StateProvinceID);

Dizinin sorguyu kapsadığını doğrulamak için dizini oluşturun ve tahmini yürütme planını görüntüleyin.

Yürütme planında yalnızca bir SELECT işleci ve IX_Address_PostalCode dizini için bir Dizin Arama işleci gösteriliyorsa, sorgu dizin tarafından karşılanmaktadır.

Aşağıdaki deyimle dizini kaldırabilirsiniz:

DROP INDEX IX_Address_PostalCode
ON Person.Address;
GO

Performansla ilgili dikkat edilmesi gerekenler

Gereksiz sütunlar eklemekten kaçının. Anahtar veya anahtar olmayan çok fazla dizin sütunu eklemek aşağıdaki performans etkilerine neden olabilir:

  • Sayfaya daha az dizin satırı sığar. Bu, G/Ç artışları ve daha az önbellek verimliliği oluşturabilir.

  • Dizini depolamak için daha fazla disk alanı gerekir. Özellikle, anahtar olmayan dizin sütunları olarak varchar(max), nvarchar(max), varbinary(max)veya xml veri türlerinin eklenmesi disk alanı gereksinimlerini önemli ölçüde artırabilir. Bunun nedeni sütun değerlerinin dizin yaprak düzeyine kopyalanmış olmasıdır. Bu nedenle, hem dizinde hem de temel tabloda bulunurlar.

  • Dizin bakımı, temel alınan tabloda veya dizine alınan görünümde değişiklik, ekleme, güncelleştirme veya silme işlemleri gerçekleştirmek için gereken süreyi artırabilir.

Sorgu performansındaki kazanımların, veri değişikliği sırasında ve ek disk alanı gereksinimlerinde performansa olan etkisinden daha ağır basıp basmadığını belirlemeniz gerekir.

Benzersiz dizin tasarımı yönergeleri

Benzersiz dizin, dizin anahtarının yinelenen değer içermediğini ve bu nedenle tablodaki her satırın bir şekilde benzersiz olduğunu garanti eder. Benzersiz bir dizin belirtmek, yalnızca benzersizlik verilerin kendisinin bir özelliği olduğunda mantıklıdır. Örneğin, NationalIDNumber birincil anahtar olduğunda, HumanResources.Employee tablosundaki EmployeeID sütunundaki değerlerin benzersiz olduğundan emin olmak için, UNIQUE sütununda bir NationalIDNumber kısıtlaması oluşturun. Kullanıcı aynı değeri birden fazla çalışan için bu sütuna girmeye çalışırsa, bir hata iletisi görüntülenir ve yinelenen değer girilemez.

Çok sütunlu benzersiz dizinlerde dizin, dizin anahtarındaki her değer bileşiminin benzersiz olduğunu garanti eder. Örneğin, , LastNameve FirstName sütunlarının MiddleNamebirleşiminde benzersiz bir dizin oluşturulursa, tablodaki iki satır bu sütunlar için aynı değer bileşimine sahip olamaz.

Hem kümelenmiş hem de kümelenmemiş dizinler benzersiz olabilir. Sütundaki veriler benzersizse, aynı tabloda hem benzersiz bir kümelenmiş dizin hem de birden çok benzersiz kümelenmemiş dizin oluşturabilirsiniz.

Benzersiz dizinlerin avantajları şunlardır:

  • Tanımlanan sütunların veri bütünlüğü sağlanır.
  • Sorgu iyileştiricisi için yararlı olan ek bilgiler sağlanır.

PRIMARY KEY Veya UNIQUE kısıtlaması oluşturmak, belirtilen sütunlarda otomatik olarak benzersiz bir dizin oluşturur. Kısıtlama oluşturma UNIQUE ile kısıtlamadan bağımsız benzersiz bir dizin oluşturma arasında önemli bir fark yoktur. Veri doğrulama aynı şekilde gerçekleşir ve sorgu iyileştiricisi bir kısıtlama tarafından oluşturulan veya el ile oluşturulan benzersiz bir dizin arasında ayrım yapmaz. Ancak, amaç veri bütünlüğü olduğunda sütunda bir UNIQUE veya PRIMARY KEY kısıtlaması oluşturmanız gerekir. Bunu yaparak, dizinin amacı açıktır.

Değerlendirmeler

  • Verilerde yinelenen anahtar değerleri varsa benzersiz bir dizin UNIQUE , kısıtlama veya PRIMARY KEY kısıtlama oluşturulamaz.

  • Veriler benzersizse ve benzersizliğin sağlanmasını istiyorsanız, aynı sütun bileşimi üzerinde benzersiz bir dizin yerine benzersiz olmayan bir dizin oluşturmak, sorgu iyileştiricisine daha verimli yürütme planları üretebilecek ek bilgiler sağlar. Bu durumda benzersiz dizin oluşturma (tercihen kısıtlama UNIQUE oluşturarak) önerilir.

  • Benzersiz bir kümelenmemiş dizin, dahil edilen anahtar olmayan sütunlar içerebilir. Daha fazla bilgi için bkz. Eklenen sütunlarla dizin oluşturma.

Filtrelenmiş dizin tasarımı yönergeleri

Filtrelenmiş dizin, özellikle iyi tanımlanmış bir veri alt kümesinden seçim yapmak için uygun olan iyileştirilmiş bir kümelenmemiş dizindir. Tablodaki satırların bir bölümünü dizine almak için bir filtre koşulu kullanır. İyi tasarlanmış bir filtrelenmiş dizin sorgu performansını artırabilir, dizin bakım maliyetlerini azaltabilir ve tam tablo dizinleriyle karşılaştırıldığında dizin depolama maliyetlerini azaltabilir.

Filtrelenmiş dizinler, tam tablo dizinlerine göre aşağıdaki avantajları sağlayabilir:

  • Geliştirilmiş sorgu performansı ve plan kalitesi

    İyi tasarlanmış bir filtrelenmiş dizin, tam tablo içermeyen bir dizinden daha küçük olduğundan ve istatistikleri filtrelediğinden sorgu performansını ve yürütme planı kalitesini artırır. Filtrelenen istatistikler, yalnızca filtrelenmiş dizindeki satırları kapsadığından tam tablo istatistiklerinden daha doğrudur.

  • Daha düşük dizin bakım maliyetleri

    Dizin yalnızca veri değiştirme dili (DML) deyimleri dizindeki verileri etkilediğinde güncellenir. Filtrelenmiş dizin, daha küçük olduğu ve yalnızca dizindeki veriler etkilendiğinde korunduğu için, tam tablodan küme dizini olmayan bir dizinle karşılaştırıldığında bakım maliyetlerini düşürür. Özellikle seyrek etkilenen veriler içerdiğinde çok sayıda filtrelenmiş dizine sahip olmak mümkündür. Benzer şekilde, filtrelenmiş bir dizin yalnızca sık etkilenen verileri içeriyorsa, dizinin boyutu daha küçükse istatistikleri güncelleştirme maliyeti azalır.

  • Daha düşük dizin depolama maliyetleri

    Filtrelenmiş dizin oluşturmak, tam tablo dizini gerekli olmadığında, kümelenmemiş dizinler için disk depolama alanını azaltabilir. Depolama gereksinimlerini önemli ölçüde artırmadan, tam tablodaki bir kümelenmemiş dizini birden çok filtrelenmiş dizinle değiştirebilirsiniz.

Filtrelenmiş dizinler, sorguların SELECT ifadelerinde başvurduğu, sütunların iyi tanımlanmış veri alt kümelerini içerdiğinde yararlıdır. Örnekler şunlardır:

  • Sadece birkaç NULL içermeyen değer barındıran seyrek sütunlar.
  • Veri kategorileri içeren heterojen sütunlar.
  • Dolar tutarları, saat ve tarihler gibi değer aralıklarını içeren sütunlar.
  • Sütun değerleri için basit karşılaştırma mantığıyla tanımlanan tablo bölümleri.

Tam tablo diziniyle karşılaştırıldığında dizindeki satır sayısı az olduğunda, filtrelenmiş dizinler için bakım maliyetlerinin daha düşük olması en belirgindir. Filtrelenen dizin tablodaki satırların çoğunu içeriyorsa, tam tablo dizinine kıyasla bakımın maliyeti daha yüksek olabilir. Bu durumda, filtrelenmiş dizin yerine tam tablo dizini kullanmanız gerekir.

Filtrelenmiş dizinler bir tabloda tanımlanır ve yalnızca basit karşılaştırma işleçlerini destekler. Birden çok tabloya başvuran veya karmaşık mantığı olan bir filtre ifadesi gerekiyorsa, bir görünüm oluşturmanız gerekir.

Tasarımla ilgili dikkat edilecek noktalar

Etkili filtrelenmiş dizinler tasarlamak için uygulamanızın hangi sorguları kullandığını ve bunların verilerinizin alt kümeleriyle ilişkisini anlamak önemlidir. İyi tanımlanmış alt kümelere sahip verilere örnek olarak çoğunlukla NULL değer içeren sütunlar, heterojen değer kategorilerine sahip sütunlar ve farklı değer aralıklarına sahip sütunlar verilebilir. Aşağıdaki tasarım konuları, filtrelenmiş bir dizinin tam tablo dizinlerine göre ne zaman avantaj sağlayabildiğine ilişkin çeşitli senaryolar sunar.

Tavsiye

Kümelenmemiş columnstore dizin tanımı, filtrelenmiş koşul kullanmayı destekler. OLTP tablosuna columnstore dizini eklemenin performans etkisini en aza indirmek için filtrelenmiş bir koşul kullanarak yalnızca işletimsel iş yükünüzün soğuk verileri üzerinde bir kümelenmemiş columnstore dizini oluşturun.

Veri alt kümeleri için filtrelenmiş dizinler

Bir sütunda sorgular için yalnızca birkaç ilgili değer olduğunda, değerlerin alt kümesinde filtrelenmiş bir dizin oluşturabilirsiniz. Örneğin, bir sütundaki değerler çoğunlukla NULL olduğunda ve sorgu yalnızca olmayanNULL değerlerden seçtiğinde, veri olmayanNULL satırlar için filtrelenmiş bir dizin oluşturabilirsiniz. Sonuçta elde edilen dizin daha küçüktür ve aynı anahtar sütunlarında tanımlanan tam tablolu bir kümelenmemiş dizinden daha düşük maliyetlidir.

Örneğin AdventureWorks örnek veritabanında 2.679 satır içeren bir Production.BillOfMaterials tablo vardır. EndDate sütunu, yalnızca 199 satırda NULL dışı bir değer içermektedir ve diğer 2480 satır NULL içermektedir. Aşağıdaki filtrelenmiş dizin, dizinde tanımlanan sütunları döndüren ve yalnızca değeri NULLolmayanEndDate satırları seçen sorguları kapsar.

CREATE NONCLUSTERED INDEX FIBillOfMaterialsWithEndDate
ON Production.BillOfMaterials(ComponentID, StartDate)
    WHERE EndDate IS NOT NULL;
GO

Filtrelenen dizin FIBillOfMaterialsWithEndDate aşağıdaki sorgu için geçerlidir. Sorgu iyileştiricisinin filtrelenmiş dizini kullanıp kullanmadığını belirlemek için Tahmini Yürütme Planı'nı görüntüleyin.

SELECT ProductAssemblyID,
       ComponentID,
       StartDate
FROM Production.BillOfMaterials
WHERE EndDate IS NOT NULL
      AND ComponentID = 5
      AND StartDate > '20080101';
GO

Filtrelenmiş dizinler oluşturma ve filtrelenmiş dizin koşulu ifadesini tanımlama hakkında daha fazla bilgi için bkz. Filtrelenmiş dizinler oluşturma.

Heterojen veriler için filtrelenmiş dizinler

Tabloda heterojen veri satırları olduğunda, bir veya daha fazla veri kategorisi için filtrelenmiş dizin oluşturabilirsiniz.

Örneğin, tabloda listelenen Production.Product ürünlerin her biri bisikletler, bileşenler, kıyafetler veya aksesuarlar ürün kategorileriyle ilişkili olan bir ProductSubcategoryIDöğesine atanır. Tablodaki sütun değerleri yakın bağıntılı Production.Product olmadığından bu kategoriler heterojendir. Örneğin , , Color, ReorderPoint, ListPrice, Weightve Class sütunları Styleher ürün kategorisi için benzersiz özelliklere sahiptir. Aksesuarlar için 27 ile 36 arasında (dahil) alt kategorilere sahip sık sık sorgular olduğunu varsayalım. Aşağıdaki örnekte gösterildiği gibi aksesuarlar alt kategorilerinde filtrelenmiş dizin oluşturarak donatılar için sorguların performansını geliştirebilirsiniz.

CREATE NONCLUSTERED INDEX FIProductAccessories
ON Production.Product(ProductSubcategoryID, ListPrice)
INCLUDE(Name)
    WHERE ProductSubcategoryID >= 27 AND ProductSubcategoryID <= 36;
GO

Sorgu sonuçları dizinde bulunduğundan ve sorgu planı temel tablo araması içermediğinden, filtrelenmiş dizin FIProductAccessories aşağıdaki sorguyu kapsar. Örneğin, sorgu koşulu ifadesi ProductSubcategoryID = 33, filtrelenmiş dizin koşulu olan ProductSubcategoryID >= 27 ve ProductSubcategoryID <= 36'nin bir alt kümesidir. Sorgu koşulundaki ProductSubcategoryID ve ListPrice sütunları hem dizindeki anahtar sütunlar olup, name ise dizinin yaprak düzeyinde eklenmiş bir sütun olarak depolanır.

SELECT Name,
       ProductSubcategoryID,
       ListPrice
FROM Production.Product
WHERE ProductSubcategoryID = 33
      AND ListPrice > 25.00;
GO

Anahtar sütunlar

Filtrelenmiş dizin tanımına birkaç anahtar veya eklenmiş sütun eklemek ve yalnızca sorgu iyileştiricisinin sorgu yürütme planı için filtrelenmiş dizini seçmesi için gereken sütunları birleştirmek en iyi yöntemdir. Sorgu iyileştiricisi, sorguyu kapsayıp kapsamadığına bakılmaksızın sorgu için filtrelenmiş bir dizin seçebilir. Ancak sorgu iyileştiricisi, sorguyu kapsıyorsa filtrelenmiş bir dizin seçme olasılığı daha yüksektir.

Bazı durumlarda filtrelenmiş dizin, filtrelenmiş dizin ifadesindeki sütunları anahtar olarak eklemeden veya filtrelenmiş dizin tanımına eklenen sütunlar eklemeden sorguyu kapsar. Aşağıdaki yönergelerde, filtrelenmiş dizin ifadesindeki bir sütunun anahtar veya filtrelenmiş dizin tanımına eklenmiş sütun olması gerektiği açıklanmaktadır. Örnekler, daha önce oluşturulan FIBillOfMaterialsWithEndDate filtrelenmiş dizine başvurur.

Filtrelenen dizin ifadesi sorgu koşuluna eşdeğerse ve sorgu filtrelenmiş dizin ifadesindeki sütunu sorgu sonuçlarıyla döndürmediyse, filtrelenmiş dizin ifadesindeki bir sütunun anahtar veya eklenmiş sütun olması gerekmez. Örneğin, FIBillOfMaterialsWithEndDate sorgu koşulu filtre ifadesiyle eşdeğer olduğundan ve EndDate sorgu sonuçlarıyla döndürülmediğinden aşağıdaki sorguyu kapsar. FIBillOfMaterialsWithEndDate filtrelenmiş dizin tanımında anahtar veya eklenmiş sütun olarak EndDate gerekmez.

SELECT ComponentID,
       StartDate
FROM Production.BillOfMaterials
WHERE EndDate IS NOT NULL;

Sorgu koşulu filtrelenmiş dizin ifadesiyle eşdeğer olmayan bir karşılaştırmada sütunu kullanıyorsa, filtrelenmiş dizin ifadesindeki bir sütun, filtrelenmiş dizin tanımında bir anahtar veya eklenen sütun olmalıdır. Örneğin, FIBillOfMaterialsWithEndDate filtrelenmiş dizinden bir satır alt kümesi seçtiğinden aşağıdaki sorgu için geçerlidir. Ancak, aşağıdaki sorguyu kapsamaz çünkü EndDate karşılaştırmada EndDate > '20040101'kullanılır ve filtrelenmiş dizin ifadesiyle eşdeğer değildir. Sorgu işlemcisi, değerlerine EndDatebakmadan bu sorguyu yürütemez. Bu nedenle, EndDate filtrelenmiş dizin tanımında bir anahtar veya dahil edilen sütun olmalıdır.

SELECT ComponentID,
       StartDate
FROM Production.BillOfMaterials
WHERE EndDate > '20040101';

Filtrelenmiş dizin ifadesindeki bir sütun, eğer sorgu sonuç kümesinde yer alıyorsa, filtrelenmiş dizin tanımında anahtar sütun veya dahil edilmiş sütun olarak bulunmalıdır. Örneğin, FIBillOfMaterialsWithEndDate sorgu sonuçlarında sütunu döndürdüğünden aşağıdaki sorguyu EndDate kapsamaz. Bu nedenle, EndDate filtrelenmiş dizin tanımında bir anahtar veya dahil edilen sütun olmalıdır.

SELECT ComponentID,
       StartDate,
       EndDate
FROM Production.BillOfMaterials
WHERE EndDate IS NOT NULL;

Tablonun kümelenmiş dizin anahtarının filtrelenmiş dizin tanımına bir anahtar veya eklenmiş sütun olması gerekmez. Kümelenmiş dizin anahtarı, filtrelenmiş dizinler de dahil olmak üzere tüm kümelenmemiş dizinlere otomatik olarak eklenir.

FIBillOfMaterialsWithEndDate ve FIProductAccessories dizinlerini bırakmak için aşağıdaki komutları çalıştırın:

DROP INDEX FIBillOfMaterialsWithEndDate
ON Production.BillOfMaterials;
GO

DROP INDEX FIProductAccessories
ON Production.Product;
GO

Filtre koşulundaki veri dönüştürme işleçleri

Filtrelenen dizinin filtrelenmiş dizin ifadesinde belirtilen karşılaştırma işleci örtük veya açık bir veri dönüştürmeyle sonuçlanırsa, dönüştürme bir karşılaştırma işlecinin sol tarafında gerçekleşirse bir hata oluşur. Çözüm, filtrelenmiş dizin ifadesini karşılaştırma işlecinin sağ tarafına veri dönüştürme işleci (CAST veya CONVERT) ile yazmaktır.

Aşağıdaki örnek, çeşitli veri türlerine sahip bir tablo oluşturur.

CREATE TABLE dbo.TestTable
(
    a INT,
    b VARBINARY (4)
);
GO

Aşağıdaki filtrelenmiş dizin tanımında sütun b , 1 sabiti ile karşılaştırmak amacıyla örtük olarak bir tamsayı veri türüne dönüştürülür. Filtrelenen önermedeki işlecin sol tarafında dönüştürme gerçekleştiğinden 10611 hata iletisi oluşur.

CREATE NONCLUSTERED INDEX TestTabIndex
ON dbo.TestTable(a, b)
    WHERE b = 1;
GO

Çözüm, sağ taraftaki sabiti, aşağıdaki örnekte görüldüğü gibi sütunuyla baynı türde olacak şekilde dönüştürmektir:

CREATE INDEX TestTabIndex
ON dbo.TestTable(a, b)
    WHERE b = CONVERT (VARBINARY (4), 1);
GO

Veri dönüştürme işleminin sol tarafından bir karşılaştırma işlecinin sağ tarafına taşınması dönüştürmenin anlamını değiştirebilir. Önceki örnekte, işleç sağ tarafa eklendiğinde CONVERT , karşılaştırma tamsayı karşılaştırmasından varbinary karşılaştırmasına değiştirildi.

Aşağıdaki ifadeyi çalıştırarak bu örnekte oluşturulan nesneleri silin:

DROP TABLE TestTable;
GO

Columnstore dizin mimarisi

Columnstore dizini, columnstore adı verilen sütunlu veri biçimini kullanarak verileri depolamaya, almaya ve yönetmeye yönelik bir teknolojidir. Daha fazla bilgi için bkz. Columnstore dizinleri: genel bakış.

Sürüm bilgileri ve yenilikler hakkında bilgi edinmek için columnstore dizinlerindeki yenilikler'i ziyaret edin.

Bu temel bilgileri bilmek, bunların nasıl etkili bir şekilde kullanılacağını açıklayan diğer columnstore makalelerini anlamanızı kolaylaştırır.

Veri depolamada columnstore ve rowstore sıkıştırması kullanılır

Columnstore dizinlerini tartışırken, veri depolama biçimini vurgulama amacıyla rowstore ve columnstore terimlerini kullanırız. Columnstore dizinleri her iki depolama türünü de kullanır.

Kümelenmiş columnstore dizininin diyagramı.

  • Columnstore, mantıksal olarak satırlar ve sütunlar içeren bir tablo olarak düzenlenmiş ve fiziksel olarak sütuna göre veri biçiminde depolanan verilerdir.

    Columnstore dizini, verilerin çoğunu columnstore biçiminde fiziksel olarak depolar. Columnstore biçiminde veriler sütunlar halinde sıkıştırılır ve sıkıştırılmış veriler açılır. Sorgu tarafından istenmeyen satırlardaki diğer değerlerin sıkıştırmalarını kaldırmaya gerek yoktur. Bu, büyük bir tablonun tüm sütununu taramayı hızlandırır.

  • Satır deposu, satırlar ve sütunlar içeren bir tablo olarak mantıksal olarak düzenlenmiş ve ardından fiziksel olarak satır başına veri biçiminde depolanan verilerdir. Bu, yığın veya kümelenmiş B+ ağaç dizini gibi ilişkisel tablo verilerini depolamanın geleneksel yolu olmuştur.

    Columnstore dizini ayrıca bazı satırları fiziksel olarak deltastore adı verilen bir satır deposu biçiminde depolar. Delta satır grupları olarak da adlandırılan deltastore, sayıca az oldukları için henüz columnstore'a sıkıştırılmaya uygun olmayan satırların saklandığı bir yerdir. Her delta satır grubu kümelenmiş B+ ağaç dizini olarak uygulanır.

  • Deltastore, columnstore'a sıkıştırılamayacak kadar az sayıda olan satırların tutulduğu bir yerdir. deltastore satırları satır deposu biçiminde depolar.

Columnstore terimleri ve kavramları hakkında daha fazla bilgi için bkz. Columnstore dizinleri: genel bakış.

İşlemler satır gruplarında ve sütun segmentlerinde gerçekleştirilir

columnstore dizini satırları yönetilebilir birimler halinde gruplandırıyor. Bu birimlerin her biri satır grubu olarak adlandırılır. En iyi performans için, bir satır grubundaki satır sayısı sıkıştırma oranlarını geliştirecek kadar büyük ve bellek içi işlemlerden yararlanacak kadar küçüktür.

Örneğin, columnstore dizini şu işlemleri satır gruplarında gerçekleştirir:

  • Satır gruplarını columnstore'da sıkıştırır. Sıkıştırma, bir satır grubu içindeki her sütun kesiminde gerçekleştirilir.
  • Silinen verileri kaldırma da dahil olmak üzere bir işlem sırasında satır gruplarını birleştirir ALTER INDEX ... REORGANIZE .
  • bir ALTER INDEX ... REBUILD işlem sırasında yeni satır grupları oluşturur.
  • Dinamik yönetim görünümlerinde (DMV'ler) satır grubu sağlığı ve parçalanma hakkında raporlar.

Deltastore, delta rowgroups adlı bir veya daha fazla satır grubundan oluşur. Her bir delta satır grubu, küçük toplu yükleri ve eklemeleri depolayan kümelenmiş bir B+ ağaç dizinidir. Bu satır grubu 1.048.576 satıra ulaştığında, "tuple-mover" olarak adlandırılan bir işlem, kapalı satır grubunu otomatik olarak columnstore'da sıkıştırır.

Satır grubu durumları hakkında daha fazla bilgi için bkz. sys.dm_db_column_store_row_group_physical_stats.

Tavsiye

Çok fazla küçük satır grubu olması columnstore dizin kalitesini düşürür. Yeniden düzenleme işlemi, silinen satırların nasıl kaldırılacağını ve sıkıştırılmış satır gruplarının nasıl birleştirileceğini belirleyen bir iç eşik ilkesi izleyerek daha küçük satır gruplarını birleştirir. Birleştirme işleminden sonra dizin kalitesi geliştirilmelidir.

SQL Server 2019 (15.x) ve sonraki sürümlerinde, demet-taşıyıcıya yardımcı olan bir arka plan birleştirme görevi, bir iç eşik tarafından belirlendiği şekilde bir süredir var olan daha küçük OPEN delta satır gruplarını otomatik olarak sıkıştırır veya çok sayıda satırın silindiği COMPRESSED satır gruplarını birleştirir.

Her sütunun her satır grubunda bazı değerleri vardır. Bu değerlere sütun segmentleri adı verilir. Her satır grubu, tablodaki her sütun için bir sütun kesimi içerir. Her sütunun her satır grubunda bir sütun kesimi vardır.

Kümelenmiş columnstore sütun kesiminin diyagramı.

Columnstore dizini bir satır grubunu sıkıştırdığında, her sütun kesimini ayrı ayrı sıkıştırır. Bir sütunun tamamını dekomprese etmek için, columnstore dizini her satır grubundan sadece bir sütun kesimini dekomprese etmelidir.

Columnstore terimleri ve kavramları hakkında daha fazla bilgi için bkz. Columnstore dizinleri: genel bakış.

Küçük yükler ve ek parçalar deltastore'a ulaşıyor.

Columnstore dizini, bir kerede en az 102.400 satırı columnstore dizinine sıkıştırarak columnstore sıkıştırmasını ve performansını geliştirir. Satırları toplu olarak sıkıştırmak için columnstore dizini küçük yükler biriktirir ve deltastore'ya ekler. Deltastore işlemleri perde arkasında yürütülür. Doğru sorgu sonuçlarını döndürmek için kümelenmiş columnstore dizini hem columnstore hem de deltastore'dan gelen sorgu sonuçlarını birleştirir.

Satırlar aşağıdaki durumlarda deltastore'a gider:

  • INSERT INTO ... VALUES deyimi ile eklendi.
  • Toplu yüklemenin sonunda sayı 102.400'den azdır.
  • Güncel -leştirilmiş. Her güncelleştirme bir silme ve ekleme olarak uygulanır.

Delta deposu ayrıca silinen, ancak henüz sütun deposundan fiziksel olarak silinmemiş olan satırlar için kimliklerin listesini de depolar.

Columnstore terimleri ve kavramları hakkında daha fazla bilgi için bkz. Columnstore dizinleri: genel bakış.

Delta satır grupları dolduğunda, sütun deposuna sıkıştırılırlar.

Kümelenmiş columnstore dizinleri, satır grubunu columnstore'da sıkıştırmadan önce her delta satır grubunda en fazla 1.048.576 satır toplar. Bu, sütun deposu indeksinin sıkıştırmasını iyileştirir. Delta satır grubu en fazla satır sayısına ulaştığında, bir OPEN durumdan duruma CLOSED geçiş yapılır. Tuple-mover adı verilen bir arka plan işlemi, kapalı satır gruplarını kontrol eder. İşlem kapalı bir satır grubu bulursa, satır grubunu sıkıştırır ve columnstore'da depolar.

Bir delta satır grubu sıkıştırıldığında, mevcut delta satır grubu, ona bir başvuru kalmadığında ve daha sonra ikiye atıcı tarafından kaldırılacak duruma geçer TOMBSTONE, yeni sıkıştırılmış satır grubu ise COMPRESSED olarak işaretlenir.

Satır grubu durumları hakkında daha fazla bilgi için bkz. sys.dm_db_column_store_row_group_physical_stats.

Dizini yeniden oluşturmak veya yeniden düzenlemek için ALTER INDEX kullanarak delta satır gruplarını columnstore'ya zorlayabilirsiniz. Sıkıştırma sırasında bellek baskısı varsa columnstore dizini sıkıştırılmış satır grubundaki satır sayısını azaltabilir.

Columnstore terimleri ve kavramları hakkında daha fazla bilgi için bkz. Columnstore dizinleri: genel bakış.

Her tablo bölümünün kendi satır grupları ve delta satır grupları vardır

Bölümleme kavramı hem kümelenmiş dizinde, yığında hem de columnstore dizininde aynıdır. Bir tablonun bölümlenmesi, tabloyu bir sütun değerleri aralığına göre daha küçük satır gruplarına böler. Genellikle verileri yönetmek için kullanılır. Örneğin, verilerin her yılı için bir bölüm oluşturabilir ve ardından verileri daha ucuz depolama alanına arşivleme amacıyla bölüm değiştirme özelliğini kullanabilirsiniz. Bölüm değiştirme, columnstore dizinlerinde çalışır ve bir veri bölümünü başka bir konuma taşımayı kolaylaştırır.

Satır grupları her zaman bir tablo bölümü içinde tanımlanır. Bir columnstore dizini bölümlendiğinde, her bölümün kendi sıkıştırılmış satır grupları ve delta satır grupları vardır.

Tavsiye

Columnstore'dan veri kaldırmanız gerekiyorsa tablo bölümleme kullanmayı göz önünde bulundurun. Artık gerekli olmayan bölümlerin değiştirilmesi ve kesilmesi, daha küçük satır gruplarına sahip olarak ortaya çıkan parçalanma oluşturmadan verileri silmeye yönelik verimli bir stratejidir.

Her bölümde birden çok delta satır grubu olabilir

Her bölümde birden fazla delta satır grubu olabilir. Columnstore dizininin bir delta satır grubuna veri eklemesi gerektiğinde ve delta satır grubu kilitlendiğinde, columnstore dizini farklı bir delta satır grubunda kilit almaya çalışır. Herhangi bir delta satır grubu mevcut değilse, columnstore indeks yeni bir delta satır grubu oluşturur. Örneğin, 10 bölümü olan bir tabloda kolayca 20 veya daha fazla delta satır grubu olabilir.

Columnstore ve rowstore dizinlerini aynı tabloda birleştirme

Kümelenmemiş dizin, temel alınan tablodaki satır ve sütunların bir kısmının veya tümünün kopyasını içerir. Dizin, tablonun bir veya daha fazla sütunu olarak tanımlanır ve satırları filtreleyen isteğe bağlı bir koşula sahiptir.

Bir satır deposu tablosunda güncelleştirilebilir bir kümelenmemiş columnstore dizini oluşturabilirsiniz. Columnstore dizini verilerin bir kopyasını depolar, böylece ek depolamaya ihtiyacınız olur. Ancak columnstore dizinindeki veriler, rowstore tablosunun gerektirdiğinden daha küçük bir boyuta sıkıştırılır. Bunu yaparak, columnstore dizininde analiz çalıştırabilir ve rowstore dizinindeki işlemleri aynı anda çalıştırabilirsiniz. Satır deposu tablosundaki veriler değiştiğinde columnstore güncelleştirilir, bu nedenle her iki dizin de aynı verilerle çalışır.

Bir columnstore dizininde bir veya daha fazla kümelenmemiş satır deposu dizini bulunabilir. Bunu yaparak, temel alınan columnstore üzerinde verimli tablo aramaları gerçekleştirebilirsiniz. Diğer seçenekler de kullanılabilir duruma gelir. Örneğin, satır deposu tablosunda bir kısıtlama kullanarak UNIQUE birincil anahtar kısıtlaması uygulayabilirsiniz. Nonunique değeri rowstore tablosuna eklenemediğinden, Veritabanı Motoru bu değeri columnstore'a ekleyemez.

Performansla ilgili dikkat edilmesi gerekenler

  • Kümelenmemiş columnstore dizin tanımı, filtrelenmiş koşul kullanmayı destekler. OLTP tablosuna columnstore dizini eklemenin performans etkisini en aza indirmek için filtrelenmiş bir koşul kullanarak yalnızca işletimsel iş yükünüzün soğuk verileri üzerinde bir kümelenmemiş columnstore dizini oluşturun.

  • Bellek içi tabloda bir sütun deposu dizini olabilir. Tablo oluşturulduğunda oluşturabilir veya daha sonra ALTER TABLE (Transact-SQL)ile ekleyebilirsiniz. SQL Server 2016(13.x) öncesinde yalnızca disk tabanlı bir tabloda columnstore dizini olabilir.

Daha fazla bilgi için bkz. Columnstore dizinleri - sorgu performansı.

Tasarım kılavuzu

  • Bir satır depolama tablosunda güncellenebilir bir sütun depolama dizini olabilir. SQL Server 2014 (12.x) öncesinde, kümelenmemiş sütun deposu dizini salt okunurdu.

Daha fazla bilgi için bkz. Columnstore dizinleri - tasarım kılavuzu.

Hash dizin tasarım yönergeleri

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. Karma dizinler, bellek için iyileştirilmiş bir tablodaki olası dizin türlerinden biridir. Daha fazla bilgi için bkz. Memory-Optimized Tablolarındaki Dizinler.

Şunlar için geçerlidir: SQL Server, Azure SQL Veritabanı ve Azure SQL Yönetilen Örneği.

Hash dizin mimarisi

Karma dizin bir dizi işaretçiden oluşur ve dizinin her öğesi karma demet olarak adlandırılır.

  • Her kova, anahtar girdilerinin bağlantı listesinin bellek adresini depolamak için kullanılan 8 bayttır.
  • Her giriş, bir dizin anahtarının değeri ve bellek ile optimize edilmiş temel tablodaki karşılık gelen satırın adresidir.
  • Her giriş, tamamı mevcut kova ile zincirlenmiş bir bağlantı listesindeki bir sonraki girişe işaret eder.

Demet sayısı dizin tanımı zamanında belirtilmelidir:

  • Demetlerin tablo satırlarına veya farklı değerlere oranı ne kadar düşükse, ortalama demet bağlantı listesi o kadar uzun olur.
  • Kısa bağlantı listeleri, uzun bağlantı listelerinden daha hızlı çalışır.
  • Karma dizinlemedeki maksimum demet sayısı 1.073.741.824'tür.

Tavsiye

Verilerinizin hakkını BUCKET_COUNT belirlemek için bkz. Karma dizin demet sayısını yapılandırma.

Karma fonksiyonu indeks anahtar sütunlarına uygulanır ve fonksiyonun sonucu bu anahtarın hangi bölmeye düşeceğini belirler. Her kova, karma anahtar değerleri bu kovayla eşlenen satırlara işaret eden bir gösterici içerir.

Karma indeksler için kullanılan karma işlevinin aşağıdaki özellikleri vardır:

  • Veritabanı Motoru'nun, tüm karma dizinler için kullanılan tek bir karma işlevi vardır.
  • Karma işlevi belirleyicidir. Aynı giriş anahtar değeri her zaman karma dizindeki aynı kova ile eşlenir.
  • Birden çok dizin anahtarı aynı karma demetine eşlenebilir.
  • Hash fonksiyonu dengelidir, yani dizin anahtar değerlerinin hash kümeleri üzerinden dağılımı, genellikle düz bir doğrusal dağılım yerine Poisson veya çan eğrisi dağılımını izler.
  • Poisson dağılımı eşit bir dağıtım değildir. Dizin anahtarı değerleri karma demetlerinde eşit olarak dağılmamaktadır.
  • Eğer iki dizin anahtarı aynı karma demetine eşlenmişse, bir karma çakışması meydana gelir. Çok sayıda karma çakışması okuma işlemleri üzerinde performans etkisi oluşturabilir. Gerçekçi bir hedef, demetlerin yüzde 30'unun iki farklı anahtar değeri içermesidir.

Karma indeksin ve demetlerin etkileşimi aşağıdaki görüntüde özetlenmiş.

Karma dizin ve demetler arasındaki etkileşimi gösteren diyagram.

Karma dizin demet sayısını yapılandırma

Karma dizin (hash index) kova sayısı, dizin oluşturulma zamanında belirtilir ve ALTER TABLE...ALTER INDEX REBUILD söz dizimini kullanarak değiştirilebilir.

Çoğu durumda demet sayısı ideal olarak dizin anahtarındaki ayrı değerlerin sayısının 1 ila 2 katı olur.
Belirli bir dizin anahtarının sahip olabileceği veya sahip olacağı değerleri her zaman tahmin edemeyebilirsiniz. Değer BUCKET_COUNT, gerçek anahtar değer sayısının 10 katı içinde yer alıyorsa performans genellikle iyi olur ve fazla tahmin yapmak genellikle az tahmin yapmaktan daha iyidir.

Çok az demet aşağıdaki dezavantajlara sahip olabilir:

  • Farklı anahtar değerlerinin daha fazla karma çakışması.
  • Her bir farklı değer, aynı kovayı başka bir farklı değerle paylaşmaya zorlanır.
  • Kova başına ortalama zincir uzunluğu artar.
  • Kovalı zincir ne kadar uzun olursa, dizindeki eşitlik aramalarının hızı o kadar azalır.

Çok fazla demet aşağıdaki dezavantajlara sahip olabilir:

  • Çok fazla kova sayısı, daha fazla boş kova ile sonuçlanabilir.
  • Boş kovalar, tam dizin taramalarının performanslarını etkiler. Taramalar düzenli olarak gerçekleştiriliyorsa, ayrı dizin anahtarı değerlerinin sayısına yakın bir demet sayısı seçmeyi göz önünde bulundurun.
  • Boş demetler bellek kullanır, ancak her demet yalnızca 8 bayt kullanır.

Uyarı

Daha fazla kova eklemek, yinelenen bir değeri paylaşan girişlerin zincirlenmesini azaltmak için hiçbir etkisi yoktur. Değer yineleme hızı, demet sayısını hesaplamak için değil, karmanın uygun dizin türü olup olmadığına karar vermek için kullanılır.

Performansla ilgili dikkat edilmesi gerekenler

Hash dizinin performansı şu şekildedir:

  • Yüklem WHERE tümcesi karma dizin anahtarındaki her sütun için tam bir değer belirttiğinde mükemmeldir. Karma indeks, eşitsizlik koşulu verildiğinde tarama moduna geri döner.
  • İndeks anahtarındaki WHEREnı arayan tümcesindeki yüklem zayıf olduğunda.
  • Yan tümce, iki sütunlu karma dizin anahtarında WHERE sütun için belirli bir değer belirtip, anahtarın diğer sütunları için değer belirtmediğinde uygun olmaz.

Tavsiye

Koşul, karma dizin anahtarındaki tüm sütunları içermelidir. Karma dizin, dizinde arama yapmak için bir anahtar (karma işlemi yapmak için) gerektirir.

Dizin anahtarı iki sütundan oluşuyorsa ve WHERE yan tümcesi yalnızca ilk sütunu sağlıyorsa, Veritabanı Altyapısı'nın karma için tam bir anahtarı yoktur. Bu, dizin tarama sorgu planıyla sonuç alır.

Karma dizin kullanılıyorsa ve benzersiz dizin anahtarlarının sayısı satır sayısından 100 kat (veya daha fazla) ise, büyük satır zincirlerini önlemek için daha büyük bir demet sayısına artırmayı veya bunun yerine kümelenmemiş dizin kullanmayı göz önünde bulundurun.

Bildirimde dikkat edilmesi gerekenler

Hash dizin yalnızca bellek iyileştirilmiş bir tabloda bulunabilir. Disk tabanlı bir tabloda bulunamaz.

Karma dizin (hash index) şöyle tanımlanabilir:

  • UNIQUEveya varsayılan olarak nonunique olabilir.
  • NONCLUSTEREDvarsayılan değerdir.

Aşağıdaki örnek söz dizimi, CREATE TABLE ifadesi dışında bir karma dizin oluşturur:

ALTER TABLE MyTable_memop ADD INDEX ix_hash_Column2
    UNIQUE NONCLUSTERED HASH (Column2) WITH (BUCKET_COUNT = 64);

Satır sürümleri ve çöp toplama

Bellek için iyileştirilmiş bir tabloda, bir satır bir UPDATEtarafından etkilendiğinde, tablo satırın güncelleştirilmiş bir sürümünü oluşturur. Güncelleştirme işlemi sırasında, diğer oturumlar satırın eski sürümünü okuyabilir ve bu nedenle satır kilidiyle ilişkili performans yavaşlamasını önleyebilirsiniz.

Karma dizin, güncelleştirmeye uyum sağlamak için girdilerinin farklı sürümlerine de sahip olabilir.

Daha sonra eski sürümlere artık ihtiyaç duyulmadığında, eski girdileri temizlemek için bir çöp toplama (GC) iş parçacığı demetleri ve bağlantı listelerini gezer. Bağlantı listesi zincir uzunlukları kısaysa GC iş parçacığı daha iyi performans gösterir. Daha fazla bilgi için bkz. In-Memory OLTP Çöp Toplama.

Bellek için iyileştirilmiş kümelenmemiş dizin tasarım yönergeleri

Kümelenmemiş dizinler, bellek için iyileştirilmiş bir tablodaki olası dizin türlerinden biridir. Daha fazla bilgi için bkz. Memory-Optimized Tablolarındaki Dizinler.

Şunlar için geçerlidir: SQL Server, Azure SQL Veritabanı ve Azure SQL Yönetilen Örneği.

Bellek içi kümelenmemiş dizin mimarisi

Bellek içi kümelenmemiş dizinler, başlangıçta 2011'de Microsoft Research tarafından öngörülen ve açıklanan Bw-tree adlı bir veri yapısı kullanılarak uygulanır. Bw ağacı, bir B ağacının kilit ve mandalsız varyasyonudur. Daha fazla bilgi için bkz. Bw ağacı: Yeni Donanım Platformları için B ağacı.

Yüksek seviyede Bw ağacı, sayfa kimliğine (PidMap) göre düzenlenmiş sayfaların bir haritası, sayfa kimliklerini tahsis etmek ve yeniden kullanmak için bir mekanizma (PidAlloc) ve sayfa haritasında birbirine bağlı bir sayfa kümesi olarak anlaşılabilir. Bu üç üst düzey alt bileşen, bir Bw ağacının temel iç yapısını oluşturur.

Yapı, her sayfanın sıralanmış bir dizi anahtar değerine sahip olması ve dizinde her biri daha düşük bir düzeye, yaprak düzeyleri ise bir veri satırına işaret eden düzeyler olması açısından normal bir B ağacına benzer. Ancak çeşitli farklar vardır.

Karma indekslerde olduğu gibi, birden fazla veri satırı (sürümler) birbirine bağlanabilir. Düzeyler arasındaki sayfa işaretçileri, sayfa eşleme tablosuna uzaklıkları olan mantıksal sayfa kimlikleridir ve bu da her sayfa için fiziksel adrese sahiptir.

Dizin sayfalarında yerinde güncelleştirme yoktur. Bu amaçla yeni delta sayfaları kullanıma sunulmuştur.

  • Sayfa güncelleştirmeleri için mandallama veya kilitleme gerekmiyor.
  • Dizin sayfaları sabit bir boyut değildir.

Gösterilen her işlev dışı düzey sayfasındaki anahtar değeri, işaret eden alt öğeye ait en yüksek değerdir ve her satır da bu sayfa mantıksal sayfa kimliğini içerir. Yaprak düzeyindeki sayfalarda, anahtar değeriyle birlikte veri satırının fiziksel adresini içerir.

Nokta sorguları B-ağaçlarına benzer, ancak sayfalar yalnızca bir yönde bağlantılı olduğu için, SQL Server Veritabanı Motoru sağ sayfa işaretçilerini izler; burada her yaprak olmayan sayfa, B-ağaçlarında olduğu gibi en düşük değer yerine alt öğesinden en yüksek değere sahiptir.

Yaprak düzeyinde bir sayfanın değişmesi gerekiyorsa, SQL Server Veritabanı Altyapısı sayfanın kendisini değiştirmez. Bunun yerine, SQL Server Veritabanı Altyapısı değişikliği açıklayan bir delta kaydı oluşturur ve önceki sayfaya ekler. Ardından, önceki sayfanın sayfa eşleme tablosu adresini, bu sayfanın fiziksel adresi haline gelen delta kaydının adresiyle de güncelleştirir.

Bw ağacının yapısını yönetmek için gereken üç farklı işlem vardır: birleştirme, bölme ve birleştirme.

Delta birleştirme

Delta kayıtlarından oluşan uzun bir zincir, bir dizinde arama yaparken uzun zincirleri incelediğimiz anlamına geldiğinden arama performansını düşürebilir. Zaten 16 öğesi olan bir zincire yeni bir delta kaydı eklenirse, delta kayıtlarındaki değişiklikler başvurulan dizin sayfasında birleştirilir ve birleştirmeyi tetikleyen yeni değişiklik kaydı tarafından belirtilen değişiklikler de dahil olmak üzere sayfa yeniden oluşturulur. Yeni yeniden oluşturulmuş sayfa aynı sayfa kimliğine ancak yeni bir bellek adresine sahip.

Bellek için optimize edilmiş sayfa eşleme tablosunu gösteren diyagram.

Sayfayı böl

Bw-tree'deki bir dizin sayfası, tek bir satırı depolamaktan en fazla 8 KB depolamaya kadar her zaman gereken şekilde büyür. Dizin sayfası 8 KB'a büyüdükten sonra, tek bir satırın yeni bir eklemesi dizin sayfasının bölünmesine neden olur. Bir iç sayfa için bu, başka bir anahtar değer ve işaretçi eklemek için yer kalmadığı anlamına gelir. Bir yaprak sayfa için ise, tüm delta kayıtları birleştirildiğinde satırın sayfaya sığamayacak derecede büyük olması anlamını taşır. Yaprak sayfanın sayfa üst bilgisindeki istatistik bilgileri, delta kayıtlarını birleştirmek için gereken alan miktarını izler. Her yeni fark kaydı eklendikçe bu bilgiler ayarlanır.

Bölme işlemi iki atomik adımda gerçekleştirilir. Aşağıdaki diyagramda, 5 değerine sahip bir anahtarın eklenmesi nedeniyle bir yaprak sayfanın bölünmeye neden olduğunu ve geçerli yaprak düzeyi sayfasının sonuna işaret eden bir yaprak olmayan sayfanın bulunduğunu varsayalım.

Bellek-optimizasyonlu indeks bölme işlemini gösteren diyagram.

1. Adım: ve P1olmak üzere iki yeni sayfa P2 ayırın ve yeni eklenen satır da dahil olmak üzere eski P1 sayfadaki satırları bu yeni sayfalara bölün. Sayfanın fiziksel adresini depolamak için P2 yeni bir yuva kullanılır. Bu sayfalar P1 ve P2 henüz hiçbir eşzamanlı işlem için erişilebilir değildir. Buna ek olarak, P1'den P2'e mantıksal işaretçi ayarlanır. Ardından, bir atomik adımda, işaretçiyi eski P1 yerine yeni P1olarak değiştirmek için sayfa eşleme tablosunu güncelleştirin.

2. Adım: Yaprak olmayan sayfa P1 işaret eder ama yaprak olmayan bir sayfadan P2 öğesine doğrudan işaretçi yoktur. P2 yalnızca P1 aracılığıyla ulaşılabilir. Bir yaprak olmayan sayfadan P2'a işaretçi oluşturmak için, yeni bir yaprak olmayan sayfa (iç dizin sayfası) ayırın, eski yaprak olmayan sayfadan tüm satırları kopyalayın ve P2'e işaret eden yeni bir satır ekleyin. Bu işlem tamamlandıktan sonra, tek ve atomik bir adımda, işaretçiyi eski yaprak olmayan sayfadan yeni yaprak olmayan sayfaya değiştirmek için sayfa eşleme tablosunu güncelleyin.

Sayfayı birleştir

Bir DELETE işlemin sonucunda sayfa boyutu üst sınırının yüzde 10'undan az olduğunda (şu anda 8 KB) veya üzerinde tek bir satır olduğunda, bu sayfa bitişik bir sayfayla birleştirilir.

Sayfadan bir satır silindiğinde, silme için bir delta kaydı eklenir. Ayrıca, dizin sayfasının (af olmayan sayfa) Birleştirme için uygun olup olmadığını belirlemek için bir denetim yapılır. Bu denetim, satırı sildikten sonra kalan alanın sayfa boyutu üst sınırının yüzde 10'undan az olup olmadığını doğrular. Uygunsa Birleştirme işlemi üç atomik adımda gerçekleştirilir.

Aşağıdaki görüntüde, bir DELETE işleminin 10 anahtar değerini sildiğini varsayın.

Bellek için iyileştirilmiş dizin birleştirme işlemini gösteren diyagram.

1. Adım: Anahtar değerini 10 (mavi üçgen) temsil eden bir delta sayfası oluşturulur ve boş olmayan sayfadaki Pp1 işaretçisi yeni delta sayfasına ayarlanır. Ayrıca özel bir birleştirme delta sayfası (yeşil üçgen) oluşturulur ve delta sayfasına işaret etmek için bağlanır. Bu aşamada, her iki sayfa da (delta sayfası ve birleştirme-delta sayfası) hiçbir eşzamanlı işlem tarafından görülemez. Atomik bir adımda, sayfa eşleme tablosundaki yaprak düzeyi sayfanın P1 göstericisi, birleştirme-delta sayfasına işaret edecek şekilde güncellenir. Bu adımdan sonra anahtar değeri 10 içindeki Pp1 girdisi, şimdi birleştirme-delta sayfasına işaret ediyor.

2. Adım: Yaprak olmayan sayfadaki 7 anahtar değerini temsil eden satırın silinmesi ve Pp1 anahtar değeri için girdinin 10 öğesini işaret edecek şekilde güncellenmesi gerekir. Bunu yapmak için, yeni bir boş olmayan sayfa Pp2 ayrılır ve anahtar değeri Pp1 satırının haricindeki tüm satırlar 7 içinden kopyalanır; ardından anahtar değeri 10 için olan satır, sayfa P1'e işaret edecek şekilde güncellenir. Bu yapıldıktan sonra, tek bir atomik adımda, Pp1'ı işaret eden sayfa eşleme tablosu girişi, Pp2'i işaret edecek şekilde güncellenir. Pp1 artık ulaşılamıyor.

Adım 3: Yaprak düzeyi sayfalar P2 ve P1 birleştirilir ve delta sayfaları kaldırılır. Bunu yapmak için yeni bir sayfa P3 ayrılır, P2 ile P1 içindeki satırlar birleştirilir ve delta sayfası değişiklikleri yeni P3 öğesine eklenir. Ardından, atomik bir adımda, sayfa P1'a işaret eden sayfa eşleme tablosu girişi, sayfa P3'e işaret edecek şekilde güncellenir.

Performansla ilgili dikkat edilmesi gerekenler

Kümeleme yapılmamış bir dizinin performansı, bellek için optimize edilmiş bir tabloyu eşitsizlik koşullarıyla sorgularken kümeleme yapılmamış karma dizinlerden daha iyidir.

Bellek açısından optimize edilmiş bir tablodaki bir sütun, hem karma indeksin hem de kümelenmemiş indeksin parçası olabilir.

Bir kümelenmemiş dizindeki bir anahtar sütunda çok sayıda yinelenen değer olduğunda, güncelleştirmeler, eklemeler ve silmeler için performans düşebilir. Bu durumda performansı artırmanın bir yolu, dizin anahtarında daha iyi seçiciliğe sahip bir sütun eklemektir.