2010-12-06 13 views
6

Yeni oluşturulmuş boş bir tabloya basit bir yabancı anahtar kısıtlaması ekleyerek birçok sorun yaşıyorum. Referans tablosu, içinde 40'tan az kayıt bulunan küçük bir dosyadır, ancak biraz referans alınacaktır. yeni tablo başarıyla oluşturuldu alır, ancak FK kısıtlamayı eklerken, bu gerçekten uzun bir süre için "düşünür" ve CPU yükü artırır:Yabancı Anahtar kısıtlaması eklemek belleği boşa harcıyor ve sayfalamaya neden oluyor

İşte böyle oluyor. Bellek kullanımı artar, sunucu çılgın gibi çağrı yapmaya başlar ve yanıt vermiyor (bağlantılar zaman aşımına uğrar). Sorguyu iptal etmek yardımcı olmaz. Çalışmakta olan tek şey, sunucuyu yeniden başlatmanın çok maliyetli olduğu.

Çalıştırmaya çalıştığım komut dosyası. SQL server gurularının yardım edebileceğini umuyorum. Teşekkürler!

USE [my_db] 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[MyNewTable](
    [Column1ID] [int] NOT NULL, 
    [Column2ID] [int] NOT NULL 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[MyNewTable] WITH CHECK ADD CONSTRAINT [FK_MyNewTable_Column1ID] FOREIGN KEY([Column1ID]) 
REFERENCES [dbo].[ReferenceTable] ([Column1ID]) 
ON UPDATE CASCADE 
ON DELETE CASCADE 
GO 

ALTER TABLE [dbo].[MyNewTable] CHECK CONSTRAINT [FK_MyNewTable_Column1ID] 
GO 

DÜZENLEME: Column1ID diğer tablolar çok başvurulmaktadır

[Column1ID] [int] IDENTITY(1,1) NOT NULL, 
[TxtCol1] [varchar](50) NOT NULL, 
[TxtCol2] [varchar](50) NOT NULL, 
[TxtCol3] [varchar](200) NOT NULL, 
[TxtCol4] [nvarchar](2000) NOT NULL, 
[TxtCol5] [varchar](200) NOT NULL, 
[BitCol1] [bit] NOT NULL, 
[TxtCol6] [varchar](200) NOT NULL, 
[NumCol1] [smallint] NOT NULL, 
[ExternalColumnId] [int] NOT NULL, 
[NumCol2] [int] NOT NULL 

(FK) 'ın: ReferenceTable şuna benzer küçük bir tablodur. ExternalColumnId, başka bir tabloya bir FK olduğunu. Sorun, ALTER TABLE çağrılarından birinde gerçekleşir. Ne yazık ki ikisi de birlikte koşuyordu, bu yüzden hangisinin neden olduğunu söyleyemem.

DÜZENLEME: DB "düşünme" moduna girdiğinde, tek bir moda geçip daha sonra çoklu kullanıcı moduna geri getirilerek geri getirilebilir. Sunucu yeniden başlatılmasından çok daha iyi ama yine de kabul edilemez.

+0

Garip. ReferenceTable'ın tanımı nedir? Hangi açıklamadan sonra hepsi yanlış gidiyor? 'İLAVE EKLE' biri? –

+0

Sadece daha fazla bilgi eklendi. Orijinal tabloda sahip olmadığım bir şey birincil anahtardır. Yeni tabloyu göz önünde bulundurarak, ne kadar bir etkisi olacağını bilemez misiniz? –

+0

Gbn haklı ve ben nesne kilidine baktığınızdan eminim. Tekrarlanabilir miydi? Yeterince sqlserver bilmiyorum, ama yeni bir tablespace oluşturmayı deneyebilirsiniz, bir sürücüde bir veri dosyası tarafından sunulan ve sorun çıkıp çıkmadığını kontrol edin. (Oracle ve sql server'ın parallels olduğunu varsayalım;)) –

cevap

4

Rastgele düşünce: Açık herhangi bir işleminiz var mı?

... (DDL çoğu yaptığı gibi) ALTER tablo özel erişim gerektirir ve bunun da sırayla diğer sorguları engeller ReferenceTable engeller bir şema kilidi, tarafından engellendiğinden, bu olabilir

+0

İş arkadaşımla görüştükten sonra DB yedeklemesi aynı anda çalışıyormuş gibi görünüyor. Ancak referans tablonun ne kadar küçük olduğunu (~ 40 kayıt) düşünürsek böyle bir soruna neden olur mu? –

+0

... Ben bir kilit CPU veya bellek kullanımı önemli ölçüde artmasına neden olmaz düşünüyorum ... – pascal

+0

@pascal: yapabilir; kilitler kaynak gerektirir, uzun bir işlem LDF büyümesine, muhtemelen daha fazla denetim noktası işlemesine, kilitli iş parçacıklarının engellenmesine ancak kendi kilitlerine sahip olmasına neden olabilir ... – gbn

0

Her sorgu grubunu ayrı ayrı çalıştırmayı öneririm.

Birincisi, tablo oluşturmak ve bu başarılı olursa görüyoruz.

Daha sonra, yabancı anahtar kısıtlamasını WITH CHECK yerine WITH NOCHECK kullanarak eklemeyi deneyin. WITH NOCHECK, MyNewTable.Column1ID içerisindeki içeriğin doğrulanmasını, kısıtlama oluştururken başvurulan tablonun sütunundaki değerlerle bastırır. MyNewTable boşsa veya birkaç satır varsa, bunun çok fazla etkisi olacağını düşünmüyordum, ancak açıkladığınız gibi belirtilerle karşılaştım - yeni kısıtlamayı alan tablonun içinde milyonlarca satır olması dışında.

Son olarak, yeni Kısıta WITH CHECK ayarlamayı deneyin için son toplu çalıştırın. onlar WITH CHECK geri ayarlanır kadar WITH NOCHECK tanımlanmış kısıtlamalar Sorgu iyileştirici tarafından göz ardı edilir çünkü bu aşağı bataklıkları, sadece WITH NOCHECK belirlenen yeni FK bırakmak gerekebilir, ancak bu önerilmez.

0

bu konu tekrarlanabilir ise, bir Microsoft Destek dava açmanızı öneririm. Bu bir böcek olabilir ve sen çarpıyorsun. Bilinen bir sorun olduğu tespit edilirse, davayı açmanız için size ücret ödeyeceklerdir.

0

şeylerin bir avuç içine bakmak - değil çözümlerin, ancak bir şeye yol açabilir.

Tanımlanmış tetikleyiciler var mı?

Veritabanı, yeni tabloyu oluşturduğunuz sırada kullanılıyor veya erişiliyor mu, yoksa boşta mı?

Başvuru tablosundaki herhangi bir şey (dağıtım sırasında veya başka bir zamanda) UPDATE Column1ID veya bu tablodaki satırları silinsin mi?

Referans tabloda Column1ID üzerinde birincil anahtar veya benzersiz bir kısıtlama var mı? (Listelenmemiş bir tane var, ama eğer mevcut olmasaydı SQL'in hatasız olacağını düşünürdüm.)

İlgili konular