sql birincil anahtarı ve dizini


106

Bir veritabanında birincil anahtar olarak ayarlanmış bir kimlik satırım (int) olduğunu varsayalım. Kimliği dışında sık sık sorgu yaparsam, onu da dizine eklemem gerekir mi? Yoksa birincil anahtar olması, zaten dizine eklendiği anlamına mı geliyor?

Sormamın nedeni MS SQL Server'da bu kimlik üzerinde bir indeks oluşturabilmem, çünkü belirttiğim gibi birincil anahtarım.

Düzenleme: ek bir soru - birincil anahtarı ek olarak indekslemenin herhangi bir zararı olur mu?

Yanıtlar:


73

Haklısınız, SQL Server'ın aynı alan (lar) üzerinde yinelenen dizinler oluşturmanıza izin vermesi kafa karıştırıcı. Ancak başka bir tane oluşturabilmeniz, PK endeksinin zaten mevcut olmadığını göstermez.

Ek dizin işe yaramaz, ancak tek zararı (çok küçük), ek dosya boyutu ve satır oluşturma ek yüküdür.


39
Kullanılmayan indekslerin hasarı gerçekten çok zararlıdır. Birincisi, dizinler depolamayı yer. Başka bir şey için, yazma ve güncellemeleri yavaşlatır. Kullanılmayacak dizinleri daima silin.
Pacerier

50

Herkesin daha önce söylediği gibi, birincil anahtarlar otomatik olarak dizine alınır.

Birincil anahtar sütununda daha fazla dizin oluşturmak, yalnızca birincil anahtarı ve diğer bazı belirli sütunları kullanan bir sorguyu optimize etmeniz gerektiğinde anlamlıdır. Birincil anahtar sütununda başka bir dizin oluşturarak ve buna bazı diğer sütunları da dahil ederek, bir sorgu için istediğiniz optimizasyona ulaşabilirsiniz.

Örneğin, birçok sütunu olan bir tablonuz var, ancak yalnızca Kimlik, Ad ve Adres sütunlarını sorguluyorsunuz. ID'yi birincil anahtar olarak alarak, ID üzerine kurulu ancak Ad ve Adres sütunlarını içeren aşağıdaki dizini oluşturabiliriz.

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

Yani, bu sorguyu kullandığınızda:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Server size sadece oluşturduğunuz dizini kullanarak sonucu verir ve gerçek tablodan hiçbir şey okumaz.


28

NOT: Bu cevap adresleri kurumsal sınıf geliştirme hakkında geniş çaplı .

Bu sadece SQL Server değil, bir RDBMS sorunudur ve davranış çok ilginç olabilir. Birincisi, birincil anahtarların otomatik olarak (benzersiz olarak) endekslenmesi yaygın olsa da mutlak DEĞİLDİR. Birincil anahtarın benzersiz bir şekilde dizine eklenmemesinin gerekli olduğu zamanlar vardır.

Çoğu RDBMS'de, eğer zaten mevcut değilse , birincil anahtar üzerinde benzersiz bir dizin otomatik olarak oluşturulur . Bu nedenle, birincil anahtar sütununda kendi dizininizi birincil anahtar olarak tanımlamadan önce oluşturabilirsiniz, ardından birincil anahtar bildirimini uyguladığınızda bu dizin veritabanı motoru tarafından (kabul edilebilirse) kullanılacaktır. Genellikle, birincil anahtarı oluşturabilir ve varsayılan benzersiz dizininin oluşturulmasına izin verebilir, ardından bu sütunda kendi alternatif dizininizi oluşturabilir ve ardından varsayılan dizini bırakabilirsiniz.

Şimdi işin eğlenceli kısmı - ne zaman benzersiz bir birincil anahtar dizini İSTEMİYORSUNUZ? Tablonuz, dizinin bakımını çok pahalı hale getirmek için yeterli veri (satır) aldığında bir tane istemezsiniz ve birini tolere edemezsiniz. Bu, donanıma, RDBMS motoruna, tablonun ve veritabanının özelliklerine ve sistem yüküne bağlı olarak değişir. Bununla birlikte, tipik olarak bir tablo birkaç milyon satıra ulaştığında ortaya çıkmaya başlar.

Temel sorun, birincil anahtar sütununun her bir satır eklemesinin veya güncellemesinin, benzersizliği sağlamak için bir dizin taramasıyla sonuçlanmasıdır. Bu benzersiz dizin taraması (veya hangi RDBMS'deki eşdeğeri), tablonun performansına hakim olana kadar tablo büyüdükçe çok daha pahalı hale gelir.

Günde iki milyar satır, 8 TB depolama alanı ve kırk milyon satır eki kadar büyük tablolarla bu sorunu defalarca ele aldım. İlgili sistemi yeniden tasarlamakla görevlendirildim, buna benzersiz birincil anahtar indeksini pratik olarak birinci adım olarak kaldırmak da dahil. Gerçekten de, biz yeniden tasarıma yaklaşmadan önce, üretimde kesintiyi kurtarmak için bu endeksi kaldırmak gerekliydi. Bu yeniden tasarım, birincil anahtarın benzersizliğini sağlamak ve verilere hızlı erişim sağlamak için başka yollar bulmayı içeriyordu.


Ya anahtar int veya bigint otomatik artış anahtarıysa? SQL Server, bu durumda benzersiz bir dizin taraması yapmayacak kadar akıllı mı?
quillbreaker

1
@quillbreaker: Bir IDENTITYalanın benzersiz olduğu garanti edilmez. Sonuçta, kullanıcılar kullanıcı iseler yinelenen değerler ekleyebilir IDENTITY_INSERT.

Bunun eski bir konu olduğunu biliyorum, ancak bir endeksin benzersizlik taramasının sisteme nasıl böyle bir yük olacağını anlamıyorum. Bir B + ağaç taraması, O (log n) * v olmalıdır, burada v, dizin parçalanması, kusurlu ağaç dengesi vb. İçin ek yük sınırlandırılmıştır. Dolayısıyla, 2 milyar satır, 2.000.000.000 (yaklaşık 31 arama) kez log tabanında 2 olacaktır. Günde 2 veya 3 veya hatta 10. 40M kesici uç yaklaşık 462 / sn'dir, uç başına ~ 100 IO ... Ahh ... Oh. Anlıyorum. Ve bu yaygın SSD'lerden önceydi.
Charles Burns

Benzersizlik kısıtlamasını kaldırmadıkça, her satırın benzersizliğini kontrol etmenin ek yükü çok daha büyük olmaz mıydı?
Max Candocia

21

Birincil anahtarlar her zaman varsayılan olarak dizine alınır.

SQL Server Management Studio veya Transact-SQL kullanarak SQL Server 2012'de bir birincil anahtar tanımlayabilirsiniz. Bir birincil anahtar oluşturmak, otomatik olarak karşılık gelen benzersiz, kümelenmiş veya kümelenmemiş bir dizin oluşturur.

http://technet.microsoft.com/en-us/library/ms189039.aspx


9

İşte MSDN'den pasaj :

Bir tablo için bir PRIMARY KEY kısıtlaması belirttiğinizde, Veritabanı Motoru, birincil anahtar sütunları için benzersiz bir dizin oluşturarak verilerin benzersizliğini zorlar. Bu dizin ayrıca sorgularda birincil anahtar kullanıldığında verilere hızlı erişime izin verir. Bu nedenle, seçilen birincil anahtarların benzersiz dizinler oluşturma kurallarına uyması gerekir.


8

kümelenmemiş belirtmezseniz, PK kümelenmiş bir dizin haline gelecektir


3

Bir PRIMARY KEYveya UNIQUEkısıtlama bildirmek , SQL Server'ın otomatik olarak bir dizin oluşturmasına neden olur.

Bir kısıtla eşleşmeden benzersiz bir dizin oluşturulabilir, ancak benzersiz bir dizine sahip olmadan bir kısıtlama (birincil anahtar veya benzersiz) var olamaz.

Buradan, bir kısıtlamanın oluşturulması:

  • aynı isimde bir dizinin oluşturulmasına neden olmak
  • Kısıtlama olmadan var olmasına izin verilmediğinden oluşturulan dizinin kaldırılmasını reddet

ve aynı zamanda kısıtlamanın kaldırılması ilişkili indeksi de düşürür.

Öyleyse, a PRIMARY KEYveya arasında gerçek bir fark var mı UNIQUE INDEX:

  • NULLdeğerlere izin verilmez PRIMARY KEY, ancak UNIQUEdizinde izin verilir ; ve küme operatörlerinde olduğu gibi (UNION, EXCEPT, INTERSECT), burada NULL = NULLiki NULLs birbirinin kopyası olarak bulunduğundan sadece bir değere sahip olabileceğiniz anlamına gelir ;
  • PRIMARY KEYTablo başına yalnızca bir tane olabilir, 999 benzersiz dizin oluşturulabilir
  • zaman PRIMARY KEYkısıtlaması oluşturulur, orada bir kümelenmiş dizin tablo üzerinde zaten ya olmadıkça kümelenmiş olarak oluşturulur NONCLUSTEREDkendi tanımında kullanılır; ne zaman UNIQUEindeks oluşturulur, bu şekilde oluşturulan NONCLUSTEREDolması özgü değildir sürece CLUSTEREDzaten yok ve böyle;

2

Bunu birincil anahtar yapmak, bunun için otomatik olarak bir dizin oluşturmalıdır.


1

SQL Server'da genellikle birincil anahtar otomatik olarak indekslenir. Bu doğrudur, ancak daha hızlı sorgulama garantisi yoktur. Birincil anahtar, birincil anahtar olarak yalnızca 1 alan olduğunda size mükemmel performans verecektir. Ancak, birincil anahtar olarak birden çok alan olduğunda, dizin bu alanları temel alır.

Örneğin: Alan A, B, C birincil anahtardır, dolayısıyla WHERE CLAUSE içindeki bu 3 alana dayalı olarak sorgulama yaptığınızda, performans iyidir, ANCAK WHERE CLAUSE'daki Only C alanıyla sorgulama yapmak istediğinizde, iyi performans elde etmeyecek. Bu nedenle performansınızı çalışır hale getirmek için C alanını manuel olarak indekslemeniz gerekecektir.

Çoğu zaman, 1 milyondan fazla rekora ulaşana kadar sorunu görmezsiniz.


0

(Ayrı) indeksi olmayan büyük bir veritabanım var.

Birincil anahtarla her sorguladığımda sonuçlar, tüm yoğun amaçlar için anında oluyor.


Bunun nedeni,
PK'nin

0

birincil anahtarlar otomatik olarak dizine alınır

kullanımınıza bağlı olarak pk kullanarak ek endeksler oluşturabilirsiniz

  • zip_code indeksi, id sık sık zip_code ve id ile seçim yapıyorsanız yardımcı olabilir
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.