Kaç veritabanı dizini çok fazla?


109

Oldukça büyük bir Oracle veritabanına sahip bir proje üzerinde çalışıyorum (sorum diğer veritabanları için de aynı derecede geçerli olsa da). Kullanıcıların neredeyse tüm olası alan kombinasyonlarında arama yapmasına olanak tanıyan bir web arayüzümüz var.

Bu aramaların hızlı olmasını sağlamak için, kullanıcıların sıklıkla arama yapacağına inandığımız alanlara ve alan kombinasyonlarına dizinler ekliyoruz. Ancak, müşterilerimizin bu yazılımı nasıl kullanacağını gerçekten bilmediğimiz için, hangi dizinleri oluşturacağımızı söylemek zor.

Uzay bir sorun değil; sadece küçük bir bölümünü kullandığımız 4 terabaytlık bir RAID sürücümüz var. Ancak, çok fazla dizine sahip olmanın olası performans cezalarından endişeleniyorum. Bu dizinlerin her satır eklendiğinde, silindiğinde veya değiştirildiğinde güncellenmesi gerektiğinden, tek bir tabloda düzinelerce dizine sahip olmanın kötü bir fikir olacağını düşünüyorum.

Peki kaç tane dizin çok fazla kabul edilir? 10? 25? 50? Yoksa gerçekten, gerçekten yaygın ve bariz durumları ele alıp diğer her şeyi görmezden mi gelmeliyim?

Yanıtlar:


87

Tabloda gerçekleşen işlemlere bağlıdır.

Çok sayıda SELECT ve çok az değişiklik varsa, istediğiniz her şeyi indeksleyin .... bunlar (potansiyel olarak) SELECT ifadelerini hızlandıracaktır.

Tablo, UPDATE'ler, INSERT'ler + DELETE'ler tarafından ağır bir şekilde vurulursa, bu işlemlerden biri her gerçekleştiğinde hepsinin değiştirilmesi gerektiğinden, çok sayıda dizinle bunlar çok yavaş olacaktır.

Bunu söyledikten sonra, hiçbir şey yapmayacak bir tabloya açıkça birçok anlamsız dizin ekleyebilirsiniz. B-Tree indekslerini 2 farklı değere sahip bir sütuna eklemek, verilere bakmak açısından hiçbir şey eklemediğinden anlamsız olacaktır. Bir sütundaki değerler ne kadar benzersiz olursa, bir dizinden o kadar çok yararlanır.


1
Sadece açıklığa kavuşturmak için, bir değer nadiren ortaya çıktığında ve ona bakmak istediğinizde, 2 değer üzerindeki dizin anlamsız olmayabilir. Yani önemli olan değerlerin ne kadar benzersiz olduğu değil, dizinin ne kadar seçici olduğuyla ilgili.
charlie_pl

44

Genelde böyle ilerlerim.

  1. Tipik bir günde veriler üzerinde çalıştırılan gerçek sorguların günlüğünü alın .
  2. En önemli sorguların yürütme planlarında dizinlere ulaşması için dizinler ekleyin.
  3. Çok fazla güncelleme veya ek içeren alanların indekslenmesinden kaçınmaya çalışın
  4. Birkaç dizinden sonra yeni bir günlük alın ve tekrarlayın.

Tüm optimizasyonlarda olduğu gibi, istenen performansa ulaşıldığında dururum (bu açıkça 0. noktanın belirli performans gereksinimlerini alacağı anlamına gelir).


26

Diğer herkes size harika tavsiyeler veriyor. İlerlerken size ek bir önerim var. Bir noktada, en iyi indeksleme stratejiniz hakkında bir karar vermeniz gerekir. Sonunda, en iyi PLANLANMIŞ indeksleme stratejisi, hala kullanılmayan indeksler oluşturabilir. Kullanılmayan dizinleri bulmanızı sağlayan bir strateji, dizin kullanımını izlemektir. Bunu şu şekilde yaparsınız: -

alter index my_index_name monitoring usage;

Daha sonra v $ object_usage'ı sorgulayarak bu noktadan sonra dizinin kullanılıp kullanılmadığını izleyebilirsiniz. Bununla ilgili bilgiler Oracle® Database Administrator's Guide'da bulunabilir. .

Bir tabloyu güncellemeden önce dizinleri bırakıp yeniden oluşturmaya yönelik bir depolama stratejiniz varsa, dizini tekrar izlemek için ayarlamanız gerekeceğini ve bu dizin için tüm izleme geçmişini kaybedeceğinizi unutmayın.


14

Veri ambarlamada yüksek sayıda dizine sahip olmak çok yaygındır. İki yüz sütunlu ve 190'ı indekslenmiş olgu tablolarıyla çalıştım.

Bunun bir ek yükü olmasına rağmen, bir veri ambarında genellikle yalnızca bir kez bir satır eklediğimiz, onu asla güncellemediğimiz, ancak daha sonra herhangi birinde indekslemeden fayda sağlayabilecek binlerce SELECT sorgusuna katılabileceği bağlamında anlaşılmalıdır. kolonlar.

Maksimum esneklik için bir veri ambarı, (sıkıştırılmış) btree dizinlerinin kullanılabildiği yüksek önem sütunları dışında genellikle tek sütunlu bitmap dizinlerini kullanır.

İndeks bakımının ek yükü çoğunlukla çok sayıda bloğa yazma masrafı ile ilişkilidir ve yeni satırlar o sütun için mevcut değer aralıklarının "ortasında" olan değerlerle eklendiğinde blok bölünmeleri ile ilişkilidir. Bu, bölümlere ayırarak ve bölümleme şemasıyla hizalanmış yeni veri yüklerini bulundurarak ve doğrudan yol ekleri kullanılarak hafifletilebilir.

Sorunuzu daha doğrudan ele almak için, ilk başta bariz olanı dizine eklemenin iyi olacağını düşünüyorum, ancak tabloya karşı sorguların yararına olacaksa daha fazla dizin eklemekten korkmayın.


Bu kadar çok gerçek mi? Boyut diyeceğinizi tahmin etmiştim. Bu oldukça tuhaf bir kullanım durumu. Ama, bir DBA olarak rock yapıyorsun, bu yüzden diyeceğim, belli ki bir şeyler kaçırıyorum.
Stephanie Page

@Stephanie, hemen hemen aynı senaryoya sahibiz .. David bunların bitmap indeksleri olduğundan bahsetti. BITMAP JOIN dizinlerini de kullanıyoruz. Evet, gerçekler üzerine. Oracle, bitmap dizinlerinde çok verimli AND işlemleri yapabilir. Örneğin, her biri bir bitmap dizinine sahip 5 düşük kardinalite niteliğine sahip WHERE yan tümcesine sahip olabilirsiniz. Yürütme planına bakarsanız, bir bitmap VE işlemlerine (temelde verimli bir bitmap ve işlem) sahip olur, ardından yürütme planında bitmap'in rowidlere dönüşümünü görürsünüz. Gerçekten hızlı.
Tagar

12

Einstein'ın bir yorumuyla basitlik hakkında birçok endeksler istediğiniz kadar ve daha fazla olarak ekleyin.

Cidden, ancak, eklediğiniz her dizin, tabloya her veri eklendiğinde bakım gerektirir. Öncelikli olarak salt okunur olan tablolarda çok sayıda dizin iyi bir şeydir. Son derece dinamik masalarda ne kadar az olursa o kadar iyidir.

Benim tavsiyem, yaygın ve bariz durumları ele almak ve daha sonra, belirli tablolardan veri alırken daha fazla hıza ihtiyaç duyduğunuz sorunlarla karşılaştığınızda, bu noktada endeksleri değerlendirin ve ekleyin.

Ayrıca, indeksleme şemalarınızı birkaç ayda bir yeniden değerlendirmek iyi bir fikirdir, sadece indeksleme gerektiren yeni bir şey olup olmadığını veya hiçbir şey için kullanılmayan ve ortadan kaldırılması gereken herhangi bir indeks olup olmadığını görmek için .


1
Yeniden değerlendirme konusunda hemfikirim. İyi bir yönetim asla bir "ayarla ve unut" görevi değildir. Yazılım değişiklikleri. Gereksinimler değişir. Kullanım değişiklikleri. Bir gün tanıtılan yeni, görünüşte önemsiz bir işlevsellik hızla en büyük darboğazınız haline gelebilir ve dünün temel ekmek ve tereyağı kodu, yalnızca kaynakları tüketen gereksiz ve gereksiz yağlara dönüşebilir. Ayrıca yinelemeli bir yaklaşıma katılıyorum. Aynı anda çok fazla şey yaparsanız, neyin işe yaradığını bilemezsiniz.
durette

6

Herkesin yükselttiği noktalara ek olarak, Maliyete Dayalı Optimize Edici, dikkate alınması gereken daha fazla kombinasyon olduğundan daha fazla dizin varsa, bir SQL ifadesi için bir plan oluştururken bir maliyet oluşturur. SQL ifadelerinin SQL önbelleğinde kalması için bağlama değişkenlerini doğru şekilde kullanarak bunu azaltabilirsiniz. Oracle daha sonra yumuşak bir ayrıştırma yapabilir ve en son bulduğu planı yeniden kullanabilir.

Her zaman olduğu gibi hiçbir şey basit değil. Eğik sütunlar ve histogramlar varsa, bu kötü bir fikir olabilir.

Web uygulamalarımızda izin verdiğimiz arama kombinasyonlarını sınırlama eğilimindeyiz. Aksi takdirde, birinin bir gün bulacağı gizli bir probleminiz olmadığından emin olmak için, kelimenin tam anlamıyla her kombinasyonu performans için test etmeniz gerekirdi. Ayrıca, uygulamanın başka bir yerinde bir şeyler ters gittiğinde sorunlara neden olan bunu durdurmak için kaynak sınırları uyguladık.


Oy verdim ama ... Fazladan ayrıştırma süresi ilginç ve akademik olsa da, doğru dizin sayısı seçimimi asla etkilemeyeceğini söyleyebilirim. Katılıyorum?
Stephanie Page

@StephaniePage Hiçbir şey kanıtlamak için bir deney yapmadım. Bununla birlikte, her sütunda saf bir şekilde tek sütunlu bir dizin oluşturan bir proje gördüm. Bazı tablolarda 80 sütun varsa, sanırım bir etki yaratmaya başlayabilir. Oracle, her dizine göre erişim maliyetini göz önünde bulunduruyor gibi görünüyor. Ama evet katılıyorum, dikkate alınması gereken daha önemli şeyler var.
WW.

Mmm ... Oracle'ın katı bir çözümlemede harcayacağı maksimum bir süre olduğuna inanıyorum ... Birkaç tablo içeren bir SQL düşünün, örneğin 7 veya 8, birleştirme sırası seçimi tek başına olası yüzlerce üretebilir erişim yolları.
Stephanie Page

6

Gerçek projem ve gerçek MySql veritabanım üzerinde bazı basit testler yaptım. Bu konuyu zaten yanıtlamıştım: Birden çok db sütununu indekslemenin maliyeti nedir?

Ama burada alıntı yaparsam daha iyi olacağını düşünüyorum:

Gerçek projemi ve gerçek MySql veritabanımı kullanarak bazı basit testler yaptım.

Sonuçlarım: bir tabloya ortalama dizin (bir dizinde 1-3 sütun) eklemek - eklemeleri% 2,1 oranında yavaşlatır. Yani, 20 dizin eklerseniz, eklemeleriniz% 40-50 daha yavaş olacaktır. Ancak seçimleriniz 10-100 kat daha hızlı olacaktır.

Öyleyse çok sayıda dizin eklemekte sorun var mı? - Duruma göre değişir :) Size sonuçlarımı verdim - Karar verin!


Tüm detaylar olmadan bu kehanet olarak alınmamalıdır. Özellikle performans kazancını / kaybını bir eylemden diğerine katlayamadığınız için. Temel aynı kalır: daha fazla dizin ekleyin ve dizin yeniden oluşturma nedeniyle eklemeleriniz sonunda daha yavaş olacaktır.
Sovyet Sınırı

3

Nihayetinde kaç tane dizine ihtiyaç duyduğunuz, uygulamalarınızın veritabanı sunucunuzun üstünde çalışan davranışına bağlıdır.

Genel olarak, ne kadar çok yerleştirirseniz, dizinleriniz o kadar acı verici hale gelir. Her ekleme yaptığınızda, bu tabloyu içeren tüm dizinlerin güncellenmesi gerekir.

Şimdi, uygulamanızda yeterli miktarda okuma varsa veya daha fazlasıysa, neredeyse tamamı okuyorsa, o zaman çok az maliyetle önemli performans iyileştirmeleri olacağı için dizinler gitmenin yoludur.


3

Bence statik bir cevap yok, bu tür şeyler 'performans ayarı' kapsamına giriyor.

Uygulamanızın yaptığı her şey bir birincil anahtar tarafından aranıyor olabilir veya sorguların, sınırlandırılmamış alan kombinasyonları üzerinden yapıldığı ve özellikle herhangi biri herhangi bir zamanda kullanılabildiği için tam tersi olabilir.

Sadece indekslemenin ötesinde, DB'nizi hesaplanan arama alanlarını, bölme tablolarını vb. İçerecek şekilde yeniden yapılandırmanız da var - bu gerçekten yük şekillerinize ve sorgu parametrelerinize, ne kadar / hangi verilerin bir sorgu tarafından yeniden yönlendirilmesi gerektiğine bağlıdır.

DB'nizin tamamı saklı yordam cepheleriyle ön plana çıkarsa, her anlık sorgu için endişelenmenize gerek kalmayacağından, dönüş biraz daha kolay hale gelir. Veya DB'nize çarpacak türden sorgular hakkında derin bir anlayışa sahip olabilirsiniz ve ayarlamayı bunlarla sınırlayabilirsiniz.

SQL Server için Veritabanı Motoru Ayarlama danışmanını yararlı buldum - 'tipik' iş yüklerini ayarlıyorsunuz ve dizin ve istatistik ekleme / kaldırma konusunda önerilerde bulunabilir. Eminim diğer DB'ler de 'resmi' veya üçüncü taraf benzer araçlara sahiptir.


3

Bu gerçekten pratikten çok teorik bir sorudur. Dizinlerin performansınız üzerindeki etkisi, sahip olduğunuz donanıma, Oracle sürümüne, dizin türlerine, vb. Bağlıdır. Dün Oracle'ın, HP tarafından yapılan, 11g veritabanıyla 10 kat daha hızlı çalışması beklenen özel bir depolamayı duyurduğunu duydum. Sizin durumunuza gelince, birkaç çözüm olabilir: 1. Çok sayıda dizine sahip olun (> 20) ve bunları günlük (her gece) yeniden oluşturun. Bu, özellikle tablo her gün binlerce güncelleme / silme alıyorsa yararlı olacaktır. 2. Tablonuzu bölümlere ayırın (bu, veri modelinize uyuyorsa). 3. Yeni / güncellenmiş veriler için ayrı bir tablo kullanın ve verileri bir araya getiren her gece bir süreç çalıştırın. Bu, uygulama mantığınızda bir değişiklik gerektirir. 4. Verileriniz bunu destekliyorsa, IOT'ye (dizin düzenlenmiş tablo) geçin.

Elbette böyle bir durum için daha birçok çözüm olabilir. Size ilk önerim, DB'yi bir geliştirme ortamına klonlamak ve ona karşı bazı stres testleri yapmak olacaktır.


Endeksleri yeniden oluşturmanın nasıl yardımcı olacağını veya bir IOT'nin nasıl yardımcı olacağını anlamıyorum.
David Aldridge

IOT - yeni bir kullanıcı tanımlı veri türü kullanılacak şekilde uygulamayı yeniden tasarlamak mümkünse, IOT tablonun indekslenmesi etrafındaki yükü kaydedecektir. burada durum bu olmayabilir. gerçekten bağlıdır. dizini yeniden oluşturma - çok sayıda dizin olması ve yeni verilerin dizine alınmaması durumunda.
Moshe

Bir IOT, blok bölünmelerinde normal bir dizinden daha fazla ek yüke sahip olan bir dizin yapısıdır. "dizinin yeniden oluşturulması - çok sayıda dizin olması ve yeni verilerin dizinlenmemesi durumunda" ... yeni girişler için dizinleri otomatik olarak tutmayan hangi RDBMS'den bahsediyorsunuz?
David Aldridge

David - tabii ki haklısın. Bunu, SQL Server'ın Tam Metin Aramasını yalnızca talebe göre indeksleme becerisiyle karıştırdım. Keşke Oracle olsaydı, çünkü bu durumda yararlı olabilirdi. Diğer iki öneriye bağlı kalmanızı tavsiye ederim.
Moshe

2

Çoğunlukla okursanız (ve birkaç güncelleme), dizine eklemeniz gereken her şeyi dizine eklememek için hiçbir neden yoktur. Sık sık güncelleme yapıyorsanız, kaç tane dizininiz olduğu konusunda dikkatli olmanız gerekebilir. Kesin bir sayı yok, ancak işler yavaşlamaya başladığında fark edeceksiniz. Verilere dayalı olarak en mantıklı olanın kümelenmiş dizininiz olduğundan emin olun.


2

Göz önünde bulundurabileceğiniz bir şey, standart bir arama kombinasyonunu hedeflemek için dizinler oluşturmaktır. Sütun1 yaygın olarak aranıyorsa ve sütun2 genellikle onunla birlikte kullanılıyorsa ve sütun3 bazen sütun2 ve sütun1 ile birlikte kullanılıyorsa, bu sırada sütun1, sütun2 ve sütun3'teki bir dizin, bu üç durumdan herhangi biri için kullanılabilir. korunması gereken tek bir dizin.


2

Bir endeks, temel tablo güncellendiğinde bir maliyet getirir. Bir dizin, bir sorguyu hızlandırmak için kullanıldığında bir fayda sağlar. Her bir endeks için, maliyeti fayda ile dengelemeniz gerekir. Sorgu dizin olmadan ne kadar yavaş çalışıyor? Bir avantajın ne kadarı daha hızlı çalışıyor? İndeks eksik olduğunda siz veya kullanıcılarınız yavaş hıza tahammül edebilir misiniz?

Bir güncellemeyi tamamlamak için gereken ek süreye tahammül edebilir misiniz?

Maliyetleri ve faydaları karşılaştırmanız gerekir. Bu sizin durumunuza özeldir. "Çok fazla" eşiğini geçen sihirli bir dizin sayısı yoktur.

Dizini depolamak için gereken alanın maliyeti de var, ancak sizin durumunuzda bunun bir sorun olmadığını söylediniz. Aynısı, disk alanının ne kadar ucuz hale geldiği göz önüne alındığında çoğu durumda geçerlidir.


1

Kaç tane sütun var? Bana her zaman çok sütunlu dizinler değil, tek sütunlu dizinler yapmam söylendi. Yani sütun sayısından daha fazla dizin yok, IMHO.


1

Esas olarak, güncellenmesinden çok daha sık kullanılacağını bilmiyorsanız (ve bu genellikle kullanım istatistiklerini toplamak anlamına gelir) bir dizin eklemeyin.

Bu kriterleri karşılamayan herhangi bir dizinin yeniden oluşturulması, kullanıldığı garip durumda sahip olmamanın performans cezasından daha pahalıya mal olacaktır.


1

Sql sunucusu, gerçekte hangi dizinlerin kullanıldığını görmenizi sağlayan bazı iyi araçlar sunar. Bu makale, http://www.mssqltips.com/tip.asp?tip=1239 , size bir dizinin ne kadar güncellendiği yerine ne kadar kullanıldığına dair daha iyi bir fikir edinmenizi sağlayan bazı sorgular verir.


0

Tamamen Where Clause'da kullanılan sütunlara dayanmaktadır. Ve Kuralın Başparmağı olarak, DEADLOCKS'tan kaçınmak için Yabancı Anahtar Sütunlarında dizinlere sahip olmamız gerekir. AWR raporu, dizin ihtiyacını anlamak için periyodik olarak analiz etmelidir.


2
Kilitlenmeleri önlemek için yabancı anahtar sütunlarındaki dizinler? Bunun neden ve nasıl olduğunu açıklayan bir referansınız var mı?
Jay Sullivan
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.