Geniş bir PK'ya karşı ayrı bir sentetik anahtar ile UQ kullanmak arasındaki performansla ilgili konular nelerdir?


10

Kayıtların birkaç geniş iş alanı ile benzersiz bir şekilde tanımlanabileceği birkaç tablo var. Geçmişte, bu alanları bir PK olarak kullandım ve şu faydaları göz önünde bulundurarak:

  • Basitlik; hiç yabancı alan yok ve sadece bir dizin var
  • Kümeleme, hızlı birleştirme birleşimlerine ve aralık tabanlı filtrelere olanak tanır

Bununla birlikte, sentetik bir IDENTITY INTPK oluşturmak ve bunun yerine iş anahtarını ayrı bir UNIQUEkısıtlamayla uygulamak için yapılmış bir dava duydum . Avantajı, dar PK'nın çok daha küçük ikincil endeksler oluşturmasıdır.

Bir tablo halinde bulunur PK dışında hiçbir indeksleri, ben büyük bir tabloda bu endeksler gelecekte gerekli olabilir varsaymak en iyisi olsa da, ikinci bir yaklaşım lehine herhangi bir neden görmüyorum ve bu nedenle dar sentetik PK lehine değil . Düşüncelerim eksik mi?

Bu arada, veri ambarlarında sentetik anahtarlar kullanmaya karşı çıkmıyorum, sadece tek bir geniş PK'nın ne zaman kullanılacağı ve dar bir PK artı geniş bir İngiltere'nin ne zaman kullanılacağı ile ilgileniyorum.


1
sitedeki diğer sorular arasında bu veya bu yararlı olabilir
Jack denemek topanswers.xyz

Yanıtlar:


11

Kümelenmiş dizin olarak doğal anahtarı kullanmanın önemli bir dezavantajı yoktur

  • kümelenmemiş dizin yok
  • bu tabloya başvuran yabancı anahtar yok (bu bir üst satırdır)

Veri ekleri, sonunda değil, veriler boyunca dağıtılacağı için olumsuz, sayfa bölünmeleri artacaktır.

FK veya NC dizinleriniz olduğunda, dar, sayısal, artan bir kümelenmiş dizin kullanmanın avantajları vardır. While business / natural anahtarını değil, NC veya FK girişi başına yalnızca birkaç bayt veri yinelersiniz.

Nedeniyle ilgili olarak Google'dan gelen 5 makaleyi de okuyun

Not "Birincil anahtar" kullanmaktan kaçındım.

Kümelenmiş dizini yedek anahtarda bulabilirsiniz, ancak PK'yi iş kurallarına göre ancak kümelenmemiş olarak saklayabilirsiniz. Sadece kümelenmiş benzersiz olduğundan emin olun çünkü SQL bunu yapmak için bir "benzersiz" ekleyecektir.

Son olarak, bir vekil anahtarın olması mantıklı olabilir, ancak her tabloda körü körüne değil : çok sayıda tablonun birine ihtiyacı yoktur veya üst tablolardan bir bileşik anahtarın yeterli olacağı yerlerde


Endeksleme referans için Bayan Tripp mükemmel makaleler için +1.
Fabricio Araujo

2
Performansın birincil anahtarlarla ve dizinlerle ilgili her şeyi ilgilendirmediği nokta için +1.
nvogel

4

Açık olanı belirtmeme rağmen, bir şeyleri kimlik numaralarına göre bulmanız gerekiyorsa, yedek anahtardaki bir dizin (kimlik numarası) yararlıdır. Kullanıcılar kimlik numarası ile uğraşmayacaklar; okunabilir metinlerle ilgilenecekler. Bu nedenle, metin ve kimlik numarasını çok fazla iletmeniz gerekir, böylece kullanıcı arayüzü metni görüntüleyebilir ve kimlik numarası üzerinde çalışabilir.

Dbms, bu şekilde tanımlarsanız yabancı anahtarları desteklemek için bu tür bir dizin kullanır.

Kimlik numaralarını yabancı anahtar olarak kullanarak bazen performansı artırabilirsiniz, ancak bu mutlak bir iyileştirme değildir. OLTP sistemimizde, doğal anahtarları kullanan yabancı anahtarlar, 130 (bence) temsilci sorgusundan oluşan bir test paketindeki kimlik numaralarını kullanarak yabancı anahtarlardan daha iyi performans gösterdi. (Önemli bilgiler genellikle anahtarlarda taşındığından, doğal anahtarları kullanmaktan çok kaçınıldı fazla birleşmeyi önlediler.) Medyan hızlanma 85 katsayısıydı (kimlik numaralarını kullanan birleşimler satırları döndürmek için 85 kat daha uzun sürdü).

Testler, kimlik numaralarındaki birleştirmelerin, belirli tablolar milyonlarca satıra ulaşana kadar veritabanımızdaki doğal anahtarlarda okunanlardan daha hızlı performans göstermeyeceğini gösterdi . Satırın genişliğinin bununla çok ilgisi vardır - daha geniş satırlar bir sayfaya daha az satır sığması anlamına gelir, bu nedenle 'n' satırları almak için daha fazla sayfa okumalısınız. Hemen hemen tüm tablolarımız 5NF; tabloların çoğu oldukça dardır.

Birleştirmeler başladığında burada basit okumalar yapın , kritik tabloları ve dizinleri katı hal diskine koymak, performansı yüz milyonlarca satıra eşitleyebilir.


3

Kümeleme + pk için kimlik sütunları kullanılarak tasarlanmış bir bütün oltp veritabanı var. Ekleme / aramalar üzerinde oldukça hızlı çalışır ama birkaç sorun gördüm:
1. ekler sadece dizin gerçekleşebilir çünkü ölçek doldurma seçeneği işe yaramaz
. Daha fazla depolama alanı. On milyonlarca kayıt içeren tablolarım var ve 1 int kendiliğinden yer kaplıyor. Onun için bir kimlik sütunu olan her tablonun iş aramaları için başka bir dizine sahip olması gerekir, bu nedenle daha fazla depolama alanı gerekir.
3. ölçeklenebilirlik. Bu en kötü problem. Her ek, dizinin sonuna gittiğinden, her ek, yalnızca dizinin sonunu vurgular (ayırma, yazma için io, vb.). Bir iş anahtarını kümeleme anahtarı olarak kullanarak, ekleri dizine eşit olarak dağıtabilirsiniz. Bu, sadece büyük bir etkin noktayı ortadan kaldırdığınız anlamına gelir. Bir dizin için daha fazla dosya kullanabilirsiniz, her dosya ayrı bir sürücüde, her sürücü ayrı ayrı çalışır.

Tablolarımı kimlik sütunlarından doğal anahtarlara değiştirmeye başladım (belki kümeleme ve pk için ayrı). Şimdi daha iyi hissettiriyor.

Ben (en azından bir oltp db için) aşağıdaki öneriyoruz:
1. bir kümeleme anahtarı olarak en sık sorgular optimize etmek için doğru sütunları doğru sırayla
kullanın 2. bir pk tablo için anlamlı sağ sütunları kullanın

Kümelenmiş anahtar basit değilse ve chars (char [], varchar, nvarchar) içeriyorsa, cevabın 'bağlıdır' olduğunu düşünüyorum, her durumu ayrı ayrı analiz etmelisiniz.

Aşağıdaki prensibi saklıyorum: en kötü durum senaryosunu en aza indirirken en yaygın sorgu için optimize edin.

Neredeyse bir örneği unutuyordum. Kendilerini referans bazı tablolar var. Bu tablonun birincil anahtarı için bir kimlik sütunu varsa, bir satır eklemek bir güncelleme gerektirebilir ve bir seferde birden fazla satır eklemek imkansız değilse zor olabilir (tablo tasarımına bağlıdır).


4
"Hotspot" konseptiniz bir efsanedir: dba.stackexchange.com/questions/1584/… Ve "Şimdi daha iyi hissettiriyor" derseniz. Kıyasladın mı?
gbn

4
Evet, yazma işlemleri doğrudan diske değil bellekte yapılır. Bir sayfaya 20 yeni satır yazarsanız, denetim noktası gerçekleştiğinde veri dosyasına yalnızca 1 fiziksel yazma olur.
mrdenny

@mrdenny, her şeyi dizinin sonuna yazacak kadar ekli olan tüm io yazma isteklerini aynı dosyaya gönderir. Normal oltp işlemlerini kullanarak bu senaryonun yeniden oluşturulması zor olduğundan şüpheleniyorum, ancak toplu / toplu kayıt ekleme gibi bazı özel senaryoları kullanmak, bazı iş verilerini taşımak için ssis kullanmak sizi oraya götürecektir.
Catalin Adler

1
@ user973156 evet tüm istekler aynı dosyaya yapılır, ancak yazma işlemleri yalnızca varsayılan olarak her dakika (varsayılan olarak) olan veya yazma arabelleği% 50 doluncaya kadar diske gitmez. Bu kuralın hala geçerli olduğu verileri nasıl yazdığınız önemli değildir.
mrdenny

2
@ user973156 Rasgele dağıtılmış bir kümeleme anahtarının kullanılması dizin parçalanmasına neden olur. Endeks parçalanması performans sorunlarına neden olacaktır. Ve tablonuz, dizin birleştirme gerçekleştirmenin "uzun zaman" alacağı ve günlük alanını ve potansiyel olarak tempDB alanını yiyeceği kadar büyüyecektir. Kimberly Tripp gibi iyi bir fikir olduğunu söyleyen insanlar olduğunda, dinliyorum. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Matt M

2

Performans açısından bakıldığında, hangi anahtarın "birincil" anahtar olduğu seçimi hiç fark etmez. Bir PRIMARY KEY ve UNIQUE bir kısıtlama ile anahtarlarınızı zorlamak arasında bir fark yoktur.

Performans, dizinlerin ve diğer depolama seçeneklerinin seçimi ve türü ile anahtarların sorgularda ve kodlarda kullanılma şekline göre belirlenir.

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.