Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:SQL Server
Azure SQL Veritabanı
Azure SQL Yönetilen Örneği
Azure Synapse Analytics
Analytics 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ü SQL
iç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:
Veritabanının özelliklerini anlayın.
- Örneğin, yüksek aktarım hızını sürdürmesi gereken sık veri değişikliklerine sahip bir çevrimiçi işlem işleme (OLTP) veritabanı mı? Bellek için iyileştirilmiş tablolar ve dizinler, mandalsız bir tasarım sağlayarak bu senaryo için özellikle uygundur. Daha fazla bilgi için bu kılavuzdaki Memory-Optimized Tablolardaki dizinler veya Memory-Optimized kümelenmemiş dizin tasarım yönergeleri ve Karma dizin tasarım yönergeleri bölümüne bakın.
- Yoksa çok büyük veri kümelerini hızlı bir şekilde işlemesi gereken bir Karar Destek Sistemi (DSS) veya veri ambarı (OLAP) veritabanı örneği mi? Columnstore dizinleri özellikle tipik veri ambarı veri kümeleri için uygundur. Columnstore dizinleri filtreleme, toplama, gruplandırma ve yıldız birleştirme sorguları gibi yaygın veri ambarı sorguları için daha hızlı performans sağlayarak kullanıcılar için veri ambarı deneyimini dönüştürebilir. Daha fazla bilgi için bu kılavuzdaki Columnstore dizinleri: genel bakış veya Columnstore dizini tasarım yönergeleri bölümüne bakın.
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.
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.
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ğiONLINE
, 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.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.
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 , ,
INSERT
UPDATE
veDELETE
deyimlerininMERGE
performansı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 birUPDATE
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
veA
sütunlarında oluşturulmuş bileşik bir dizine sahip olan bir tabloda,B
veC
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ümWHERE
veJOIN
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
LastName
FirstName
tanımlanırsa, dizin, arama ölçütüWHERE LastName = 'Smith'
veyaWHERE LastName = Smith AND FirstName LIKE 'J%'
olduğunda yararlıdır. Ancak, sorgu iyileştiricisi yalnızca üzerindeFirstName (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 FILLFACTOR
bir 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
deyimindekiDROP INDEX
yan tümcesinde yeni bir dosya grubu veya bölüm düzeni belirterek ya daCREATE INDEX
deyiminiDROP_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 RejectedQty
Purchasing.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.
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
.
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.
- sys.column_store_dictionaries
- sys.column_store_row_groups
- sys.column_store_segments
- sys.dm_column_store_object_pool
- sys.dm_db_column_store_row_group_operational_stats
- sys.dm_db_column_store_row_group_physical_stats
- sys.dm_db_index_operational_stats
- sys.dm_db_index_physical_stats
- sys.dm_db_xtp_hash_index_stats
- sys.dm_db_xtp_index_stats
- sys.dm_db_xtp_nonclustered_index_stats
- sys.dm_db_xtp_object_stats
- sys.dm_db_xtp_table_memory_stats
- sys.hash_indexes
- sys.index_columns
- sys.indexes
- sys.internal_partitions
- sys.memory_optimized_tables_internal_attributes
- sys.partitions
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.
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
veyaGROUP BY
yan tümcelerini kullanın.ORDER BY
veyaGROUP 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şturulabilirLastName
FirstName
MiddleName
.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 belirleyici
PRIMARY KEY
olarak kullanılıyorsa, bunun kümelenmemiş bir dizin olarak oluşturulması ve kümelenmiş dizini oluşturmak içinIDENTITY
gibi başka bir sütunun kullanılması önerilir.Sırayla erişilir
Örneğin, bir ürün kimliği veritabanındaki tablodaki
Production.Product
AdventureWorks2022
ü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
IDENTITY
tanı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 ManagerID
ile 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.
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 , ,
INSERT
UPDATE
veDELETE
deyimlerininMERGE
performansı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
veyaGROUP 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
ifadesininCREATE INDEX
yan tümcesi, üzerinde çalışılan sorgununWHERE
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
veA
sütunlarında benzersiz olmayan kümelenmemiş bir dizin olur ve anahtar değer sütunlarıB
,A
veC
ş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
ve0
gibi ç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ğerlerin0
çoğu ise, sorgu iyileştiricisi içeren1
veri 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
ifadesininCREATE 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 NULL
NULL
null 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, , LastName
ve FirstName
sütunlarının MiddleName
birleş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 veyaPRIMARY 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 NULL
olmayanEndDate
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
, Weight
ve Class
sütunları Style
her ü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 EndDate
bakmadan 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 b
aynı 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.
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.
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 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
WHERE
nı 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:
-
UNIQUE
veya varsayılan olarak nonunique olabilir. -
NONCLUSTERED
varsayı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 UPDATE
tarafı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.
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.
1. Adım: ve P1
olmak ü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 P1
olarak 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.
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.
İlgili içerik
- İNDEKS OLUŞTUR (Transact-SQL)
- Sorgu performansını geliştirmek ve kaynak tüketimini azaltmak için dizin bakımını iyileştirme
- Bölümlü tablolar ve dizinler
- Memory-Optimized Tablolardaki Dizinler
- Columnstore dizinleri: genel bakış
- Hesaplanan sütunlardaki dizinler
- Kümelenmemiş dizinleri eksik indeks önerileri kullanarak iyileştirin