Ofisimde oldukça çirkin, ancak üretimde ve geliştirme ortamında oldukça iyi çalışan bir sorgu var (sırasıyla 20sn ve 4sec). Ancak test ortamımızda 4 saatten fazla sürer. SQL2005 (+ en son yamalar) üretim ve geliştirmede çalışıyor. Test sırasında SQL2008R2 çalışıyor.
Sorgu Planına bir göz attım ve SQL2008R2'nin döndürülen satırları bağlantılı sunucudan depolamak için bir Tablo Biriktirme (tembel biriktirme) aracılığıyla TempDB kullandığını gösteriyor. Bir sonraki adım, sorgunun% 96,3'ünü tüketen Yuvalanmış Döngüler'i (sol anti yarı birleşim) gösteriyor. İki operatör arasındaki hat 5.398 MB'tır!
SQL 2005 için sorgu planı tempdb ve sol anti yarı birleştirme kullanımını gösterir.
Sterilize edilmiş kod ve yürütme planları 2005 planını en üstte, 2008R2 en altta planlıyor.
Sert yavaşlama ve değişime neden olan nedir? Farklı bir infaz planı görmeyi bekliyordum, bu beni rahatsız etmiyor. Sorgu süresindeki dramatik yavaşlama beni rahatsız eden şey.
Altta yatan donanıma bakmalı mıyım, 2008R2 sürümü tempdb kullandığından bunun kullanımını nasıl optimize edebileceğime bir göz atmam gerekiyor mu?
Sorguyu yazmanın daha iyi bir yolu var mı?
Yardım için teşekkürler.
INSERT INTO Table1_GroupLock (iGroupID, dLockedDate)
SELECT
Table1.iGroupID,
GETDATE()
FROM Table1
WHERE
NOT EXISTS (
SELECT 1
FROM LinkedServer.Database.Table2 Alias2
WHERE
(
Alias2.FirstName + Alias2.LastName = dbo.fnRemoveNonLetter(Table1.FullName)
AND NOT dbo.fnRemoveNonLetter(Table1.FullName) IS NULL
AND NOT Alias2.FirstName IS NULL
AND NOT Alias2.LastName IS NULL
) OR (
Alias2.FamilyName = dbo.fnRemoveNonLetter(Table1.FamilyName)
AND Alias2.Child1Name = dbo.fnRemoveNonLetter(Table1.Child1Name)
AND NOT dbo.fnRemoveNonLetter(Table1.FamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.Child1Name) IS NULL
AND NOT Alias2.Familyname IS NULL
AND NOT Alias2.Child1Name IS NULL
) OR (
Alias2.StepFamilyName = dbo.fnRemoveNonLetter(Table1.StepFamilyName)
AND Alias2.StepFamilyNameChild1 = dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2)
AND NOT Alias2.StepFamilyName IS NULL
AND NOT Alias2.StepFamilyNameChild1 IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyName) IS NULL
AND NOT dbo.fnRemoveNonLetter(Table1.StepFamilyNameChild2) IS NULL
)
) AND NOT EXISTS (
SELECT 1
FROM Table3
INNER JOIN Table4
ON Table4.FirstNameType = Table3.FirstNameType
INNER JOIN table5
ON table5.LastNameType = Table3.LastNameType
WHERE
Table3.iGroupID = Table1.iGroupID
AND Table3.bIsClosed = 0
AND Table4.sNameTypeConstant = 'new_lastname'
AND table5.sFirstNameConstant = 'new_firstname'
)


:: EDIT :: Sorguyu, farklı bir SQL2005 örneğinden, hemen hemen "iyi olanla" aynı yürütme planıyla yürüttüm. İki 2005 sürümünün 2008R2 bağlantılı sunucuda nasıl çalıştığından emin değilsiniz, 2008R2 örneklerinin 2008R2 örneklerinden daha iyi.
Kodun bazı işleri kullanabileceğini inkar etmese de, sorun olan kod olsaydı, tüm denemelerimde aynı 'exec exec planlarını göremez miydim? SQL sürümünden bağımsız olarak?
:: EDIT :: Her iki 2008R2 örneğine de SP1 ve CU3 uyguladım, hala zar yok. Özellikle bağlı sunucuda kollokasyon ayarladım, zar yok. Özellikle kullanıcı acct izinlerini her iki örnekte sysadmin olacak şekilde ayarladım, zar yok. Ayrıca sql server 2008 dahili ve sorun giderme hatırladım, biz bunu nasıl izleyebilir miyim göreceğiz.
Yardım ve ipuçları için herkese teşekkürler.
:: EDIT :: Bağlantılı sunucuda çeşitli izin değişiklikleri yaptım. Ben SQL girişleri, etki alanı girişleri kullandım, ben kimliğine bürünmüş kullanıcılar, "Bu güvenlik bağlamı kullanılarak yapılabilir" seçeneğini kullandım. Bağlı sunucunun her iki tarafında sunucuda sysadmin hakları olan kullanıcılar oluşturdum. Fikirlerim tükendi.
Hala neden SQL2005 sorguyu SQL2008R2 çok dramatik bir şekilde farklı yürütüyor bilmek istiyorum. Kötü bir sorgu olsaydı, SQL2005 ve SQL2008R2 üzerinde 4 + saat çalışma süresi görecektim.