Veritabanını endeksleme


12

Veritabanlarına pek aşina değilim ve şimdi indeksleme mekanizmasını anlamaya çalışıyorum.

Bildiğim kadarıyla, bir RDBMS'de, bir sütunda dizinleme, bu sütuna göre aramayı daha hızlı hale getirir. Bu, üçlü mağazalar için de geçerlidir, sadece orada endeksler çoğunlukla örneğin konuya, sonra nesneye göre arama yapacağınızı varsayar.

RDBMS hakkında emin değilim, ancak üçlü mağazalarda birden fazla dizin tanımlayabilirsiniz, mağaza her sorgu için en iyi dizin seçmesine izin (umarım bu hakkı anladım). Doğal olarak, aşağıdaki soru ortaya çıkıyor:

Neden olası tüm dizinleri üçlü bir mağazaya eklememeliyim ve bir RDBMS'ye genişletmeliyim, neden her sütunda dizin oluşturmuyorum (çok tembel olmadığımı varsayarak)?

Yanıtlar:


25

Çünkü, temelde, bir dizin fazladan bir tablodur, burada birincil anahtar dizine eklediğiniz alan ve tek içerik ana tablonuzun birincil anahtarıdır. Bu nedenle, her güncellemenin, güncelleştirdiğiniz alanı kullanan her dizinde çoğaltılması gerekir.

Bu özellikle Uçlar için fark edilir. Bir tabloya yaptığınız her ekin diğer 20 tabloda çoğaltılması gerekip gerekmediğini düşünün. Acı verici bir şekilde yavaş olacak.

Bunun bileşik, kümelenmiş ve tam metin dizinleri ile daha da kötüleştiğini unutmayın, ancak sorunu sizin için henüz karmaşıklaştırmak istemiyorum.


2

Endeksler temel olarak oluşturulması ve depolanması gereken ek veri yapılarıdır. Bina gerçekten CPU gücünü (yazma işlemleri sırasında) ve depolamak disk kapasitesini boşa harcar.

Neden hiç kullanmadığınız dizinler oluşturmak ve saklamak istersiniz?


Bu tamamen teorik bir sorudur ("ya ne olursa olsun / olmasın").
Dragos

@Dragos Bence bu sorunun cevabı yazıma göre belli: Eğer yazdıysanız, her yazma işlemi yavaşlar ve her kayıt çok fazla disk kapasitesini boşa harcar. Neden olmasın? Çünkü CPU gücü ve disk depolama pahalıdır.
Matěj Zábský

2

Dizinleri yalnızca gerektiğinde yerleştirin. Bir veritabanı şeması geliştirirken genel bir kural olarak, her tablo başlamak için bir PK Birincil Anahtar Kümelenmiş Dizini alır. Bu, tablodaki veriler için benzersiz tanımlayıcı olacaktır. İçinde 1 sütun veya daha fazla olabilir.

Bundan sonra, genellikle yalnızca benzersizliği zorunlu kılmak istediğim sütunlara Kümelenmemiş Benzersiz Dizinler eklerim.

Bu temel şemadır. Uygulama geliştikçe ve olgunlaştıkça, performans endişelerine ve verileri nasıl sorguladığımıza bağlı olarak gerektiğinde dizinler ekliyoruz.

Eklenen her endeks, ek aralıklarla bakımın yanı sıra kullanılan aralığı da artırır. Dizinlerinizi akıllıca seçin.


Cevabınızı okurken başka bir soru aklıma geldi: Birincil Anahtarlar genellikle otomatik olarak dizine ekleniyor mu yoksa kendime dizine ekleneceğini belirtmem gerekiyor mu? Örneğin, bir MySQL veritabanında mı?
Dragos

Evet, birincil anahtar (SQL Server) için otomatik olarak kümelenmiş bir dizin oluşturmalıdır. Yalnızca bir birincil anahtar, böylece tablo başına yalnızca bir kümelenmiş dizin. MySQL benzer olmalıdır, ancak bir MySQL uzmanı doğrulayabilir.
Jon Raynor

2

Dizinlerin gücü, 1) hızlı bir şekilde aranabilen bir veri yapısı ve 2) gerçek tablolardan daha kompakt olması ve dizinin daha fazlasının diske disk belleği yerine belleğe sığmasına izin vermesidir.

Her sütunda bir dizin varsa, dizinlerin kendileri temsil ettikleri tablodan daha fazla yer kaplar. Veritabanı gerçekten tüm dizinleri kullanıyorsa, sadece onları bellekte ve bellekte değiştirmek için daha fazla zaman gerekir. Ayrıca, her dizin bir eylemsiz, güncelleme veya silme işleminde güncellenmelidir.

Bunun ötesinde, tek bir sütundaki dizinler yapabileceğiniz en iyi şey değildir. İlişkisel veritabanlarının çoğu aslında birden çok sütunda bir dizine izin verir ve bu sütunların sırası önemlidir. Örneğin, 1980-1984 yılları arasında derslerden Duke'e giden tüm insanlar için bir veritabanı aramak istersem, o zaman istediğim (School, ClassYear) dizinidir. Sorgu aynı sütunlara sahip bir dizini kullanamaz, ancak tersine çevirir.

Bu nedenle, olası her dizini oluşturmak için en az n! dizindeki sütunları düzenleme yolları. Yalnızca 5 sütunla 120 olası dizin vardır.

Olası çok sayıda dizin olduğundan, uygulamanız için hangi dizinlerin yararlı olduğunu belirlemeniz ve yalnızca bunları oluşturmanız gerekir.


Ancak, örnek iki dizinde: biri Okul diğeri ClassYear olmak üzere her durumda yararlı olur mu?
Dragos

@Dragos Elbette, olabilirler. Yalnızca Sınıf Yılında olan bir başka sorgum olsaydı (2004 sınıfında bir okula giden tüm öğrenciler) Sınıf Yıl endeksi yararlı olabilir. Ne yazık ki, sorgu motorunun hangi dizinin ne zaman kullanılacağına karar verirken kullandığı bir ton faktör vardır. O veritabanında bireylerin yarısının ortaya çıkarsa vermedi 2004 yılında okula gitmek, sonra da veritabanı sadece endeksi göz ardı edebilir ve her durumda tüm tabloyu üzerinde tarayın. Bu konuda iyi olmak istiyorsanız, yürütme planlarını
Chris Pitman

Demek istediğim, Okul ve ClssYear hakkında ayrı dizinlerim olsaydı, 1980-1984 yılları arasında Duke'a giden tüm insanları ararken faydalı olurlar mıydı?
Dragos

@Dragos Belirli bir db motoruna bağlıdır. Örneğin, Postgres , birden çok dizinin sonuçlarını kesmek için Bitmap Dizin Taraması adı verilen bir şey kullanır . Hangi dizinin kullanılacağına karar vermek sorgu motoruna bağlıdır ve bu her zaman db'ye özgü olacaktır.
Chris Pitman

2

Bir tablodaki her sütun için bir dizin oluşturmak genellikle alan kaybıdır ve diğerlerinin de belirttiği gibi ekleme / güncelleme işlemlerini yavaşlatabilir. Sorguları hızlandırmak için bir dizin kullanılır. Yalnızca bir sütundaki değerleri sorgularken düşük performans fark ederseniz bir sütuna bir dizin eklemenizi öneririm.

Bazı veritabanları, tablonun birincil anahtarı için bir dizin gerektirebilir, bu nedenle bununla ilgili bir seçiminiz olmayabilir. Ayrıca, çok büyük bir metin sütununuz varsa, tam metin arama ve dizin için tasarlanmış belirli teknolojiler vardır, ancak bunlar her zaman küçük bir sayısal sütun için kullanacağınız dizin türleri ile aynı değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.