Başlangıçtan itibaren veya performans sorunu ortaya çıktığında dizin oluşturma?


15

Benim sorum dizin kullanımı ile ilgili.

  1. Dizine eklemeyi hemen en başından itibaren mi yoksa performans sorunu ortaya çıktığında mı?

  2. Bir sorguyu yürütürken geçici dizin de oluşturabiliriz. Bu tekniklerin artıları ve eksileri nelerdir?

Yanıtlar:


17

Dizine eklemeyi hemen en başından itibaren mi yoksa performans sorunu ortaya çıktığında mı?

Dizin oluşturma stratejisi, kullanım modelleri ortaya çıktıkça evrimleşme eğilimindedir. Bununla birlikte, ön tarafta uygulanabilecek stratejiler ve tasarım kılavuzları da vardır.

  • İyi bir kümeleme anahtarı seçin . Genellikle bir tabloya eklenen ekleme desenine bağlı olarak tasarım zamanında uygun kümelenmiş dizini belirleyebilirsiniz. Gelecekte bir değişiklik için zorlayıcı bir durum ortaya çıkarsa, öyle olsun.

  • Birincil ve diğer benzersiz kısıtlamalarınızı oluşturun . Bunlar, benzersiz dizinlerle uygulanacaktır.

  • Yabancı anahtarlarınızı ve ilişkili kümelenmemiş dizinleri oluşturun . Yabancı anahtarlar en sık başvurulan birleştirme sütunlarınızdır, bu nedenle onları başlangıçtan itibaren dizine ekleyin.

  • Oldukça seçici olan sorgular için dizinler oluşturun . Zaten bildiğiniz sorgu kalıpları için oldukça seçici olacaktır ve taramalar yerine aramalar kullanması muhtemeldir.

Yukarıdakilerin ötesinde, yeni endekslerin uygulanmasına kademeli ve bütüncül bir yaklaşım getirin. Bütünsel olarak, bir eklemeyi değerlendirirken tüm sorgular ve mevcut dizinler için potansiyel fayda ve etkiyi değerlendirmeyi kastediyorum.

SQL Server çevrelerinde nadir olmayan bir sorun, eksik dizin DMV'lerden ve SSMS ipuçlarından gelen rehberlik sonucu overindexing'dir. Bu araçların hiçbiri mevcut dizinleri değerlendirmez ve mevcut 5 sütun dizinine tek bir sütun eklemek yerine, yeni bir 6 sütun dizini oluşturmanızı önerir.

-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
)

-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

Kimberly Tripp , SQL odaklı diğer platformlar için geçerli iken endeksleme stratejisi üzerinde bazı mükemmel malzeme vardır. SQL Server folk için, yukarıdaki örnek gibi kopyaları tanımlamak için bazı kullanışlı araçlar vardır .

Bir sorguyu yürütürken geçici dizin de oluşturabiliriz. Bu tekniklerin artıları ve eksileri nelerdir?

Bu genellikle yalnızca nadiren çalıştırılan sorgular, tipik olarak ETL için geçerlidir. Değerlendirmeniz gerekiyor:

  1. Dizin oluşturmak için geçen süre, sorgunun yürütme süresini azaltır mı?
  2. Dizini yerinde bırakma bakım yükü, gerektiğinde oluşturma / bırakma için geçen süreden daha ağır mı?

3
+1 Kümeleme Anahtarı, Yabancı Anahtar, Benzersiz / Birincil Anahtar ve eksik endeks DMV'lerine nominal değerde güvenmemek ... Tüm bunlar harika bir tavsiye. SQL Server'da varolan dizinlerle başa çıkmak, sys.dm_db_index_usage_stats DMV kullanılarak izlenmek oldukça kolaydır. Belirli bir süre boyunca taranmamış veya aranmamış dizinleri listelerken aynı dizinlerin birkaç kez güncellendiğini görebilirsiniz. Bu overindexing'in bir göstergesidir.
Matt M

1
Ancak +1, 'açıkça seçici olan sorgular için dizinler oluştur'. diğer tüm senaryoları kapsamaz. Dizinler, sorgularınız çok seçici olmasa bile sonuçların sıralanmasına yardımcı olabilir. Seçilen tüm sütunları kaplarlarsa sorguları da hızlandırabilirler.
Unreason

1
Anlaşıldı, ancak soru oyunun sonundan ziyade bir başlangıç ​​noktası arıyordu. Hepsini nadiren karşılayabileceğiniz için, kullanım kalıpları olmadan sorgulanacak konuları belirlemek zordur.
Mark Storey-Smith

8

Her iki yaklaşımla da gerçekten riskler var:

Seçenek a) Başlangıçtan itibaren dizin, ancak asla kullanılmayan bir dizi dizin oluşturduğunuzu fark etmeyin. Bunlar bazı ek yükler ekler (en belirgin şekilde verileri değiştiren sorgulara değil, aynı zamanda en iyi dizini belirlemeye çalışan SELECT ifadelerinin optimizasyonu ile).

Artık kullanılmayan dizinleri tanımlamak ve bunları kaldırmak ve denemek için kendinizi disipline etmeniz gerekecektir (PostgreSQL bunu yapabilir; maalesef MySQL, kutudan çıkarken çok zayıf.)

Seçenek b) Kişiler şikayet etmeye başlayana kadar dizin eklemeyin veya tanılama araçlarınız belirli sorguların yavaş olduğunu ve geliştirilebileceğini tetikler.

Sunma riskiniz, dizine ihtiyacınız olduğunu fark ettiğiniz zaman ile eklemeniz gereken zaman arasında yeterince büyük bir zaman aralığınızın olmamasıdır.

PostgreSQL, CONCURRENTLYbu ani endeks-ekleme gereksinimindeki stresin bir kısmını azaltan bina indekslerini destekliyor , ancak kılavuzda not edilen bazı uyarılar var .


Seçenek (b) benim tercihim olma eğilimindedir, ancak her iki seçeneğin bir melezinin muhtemelen en iyi çözüm olduğunu düşünüyorum. Bir endeksin gerçekten kullanılacağını düşünüp düşünmediğinize dair güven seviyenizle ilgilidir.

Bunu özellikle karmaşık bir tartışma yapan şey, dizinleri değiştirmenin genellikle kolay olması, ancak şemayı değiştirmenin daha zor olmasıdır. B'nin gecikmesiz tepkisini umursamaz olmak için bir bahane olarak teşvik etmek istemiyorum .


4

Mark'ın cevabına ek olarak

Beklenen miktarlarda gerçekçi test verilerine sahip olarak bir fikir edinebilirsiniz. Bir sorgunun 1000 satırla sorunsuz çalıştığı, ancak milyonlarca üretimin olmadığı birçok, çok (çok) durum gördüm.

Yapabiliyorsanız, daha sonra üretimin bir kopyası üzerinde çalışın,

Tabii ki, garip sorunu sadece üretimde gördüm, çünkü her şey aynı olduğunda kullanım kalıpları

Geçici dizinler? ETL yük desenlerinin dışında, bir kez ihtiyacınız varsa tekrar ihtiyacınız olacak. Unutmayın: bir dizin oluşturma / bırakma bir yazmadır ve günlüğe kaydedilir = daha fazla yükleme


3

Sadece birkaç şey eklemek için.

  • Geçici endeksler korkunç bir fikirdir. Endeks geçici bir tabloda yoksa.
  • Endeksler, insanların fark ettiğinden çok daha fazla veri alanı (ve diğer ek yük) alır. Bu nedenle, onları tutucu bir şekilde oluşturun.

Bu benim yaklaşımım.

  1. Mark'a benzer şekilde, mantıklı oldukları yerlerde dizinler oluşturun, ancak gecikmeyin.
  2. Yeni dizinler oluşturmak için performansın yavaşlamasını beklemek zorunda değilsiniz. Yeni SQL yazdığınızda, bir sorgu planı çalıştırın (tercihen prod veritabanınıza karşı). Yeni bir dizin gerekip gerekmediğini görebilmeniz gerekir.
  3. Kullanılmayan sütunlar için nereye > 0veya > ""nereye koyduğunuzdan korkmayın .

    1. Yani, A, B, C ve D'de bir endeksiniz olduğunu varsayalım. Ancak, sadece A, B, D bilgilerine sahipsiniz. Yapamamanın bir sebebi yok.
    select * from blah 
    where A="one" 
    and B="two" 
    and C>=""     --to match index
    and D="four"
    
    --This will use your existing index. No need to create a redundant one.

Başka bir şey, bu "dba" forumunda, ancak dizin oluşturma dba değil, gerçekten geliştiricinin sorumluluğu olmalıdır. (Tamamen ayrı oldukları durumlar için)
user606723 17:11

2
Dizinler tarafından alınan alana ilişkin ifadeniz biraz yanıltıcıdır, kümelenmemiş bir dizinde çok az ek yük vardır. Bu noktada bir soru gönderebilirseniz daha fazla araştırmaya değer. İkinci olarak, dizin oluşturmanın geliştiricinin alanı olduğunu kabul etmiyorum. Geliştirici ve DBA arasındaki işbirliğinin en iyi sonuçları verebileceği alanlardan biri.
Mark Storey-Smith

1
Size tablolarımızdan birine bir örnek vereceğim. tablo boyutu: 21052404 KB. Bu tablodaki kümelenmemiş bir dizinin boyutu: 6637470 KB. Çok az ek yük? Bence değil. Ayrıca, DBA'larla işbirliği yapılmaması gerektiğini söylemiyorum, yeni bir endeksin oluşturulup oluşturulmayacağını belirlemenin geliştiricinin sorumluluğu olması gerektiğini söylüyorum. SQL yazmamalı ve dbas'ın bunu kendi başına çözmesini beklememelidirler.
user606723

1
Bağlam olmadan böyle numaralar veremezsiniz. NC dizin sütunlarını ve kümelenmiş anahtarı belirtmeden, genel giderlerin ve verilerin oranını hesaplamak imkansızdır.
Mark Storey-Smith

Touché. Anahtar bir [sayısal (24), karakter, tarih] ve NC sütunları [tarih, sayısal (24)] şeklindedir. (Bu belirli dizinde yalnızca iki sütun).
user606723

2

Sadece ilk soruyu cevaplamaya çalışacağım. Belirli bir süre sonra tablolarınızda kaç kayıt olacağını kabaca en başından tahmin edebiliyorsanız, bazı endeksler tasarlamak için baştan başlamak daha iyi olduğunu söyleyebilirim. En sık kullanılacağını düşündüğünüz uygulama çağrıları için mümkün olduğunca çok çağrıyı otomatikleştirecek bazı test araçlarını veya test komut dosyalarını kullanmaya çalışın ve en başta hangi tablo taramalarının önlenebileceğini göreceksiniz.

Başlangıçta bir tahmin çalışması olacak, ancak zamanla, uygun kullanım istatistiklerine sahip olduğunuzdan, daha net bir görüntünüz olacak.

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.