Bir veritabanının profilini oluştururken , bu uygulamanın havuzundaki her bağlantı için dakikada 1000-2500 kez erişilen belirleyici olmayan bazı işlevlere gönderme yapan bir görünümle karşılaştım . Görünümden bir basit aşağıdaki yürütme planını verir:SELECT
Bu, birkaç ayda bir veya iki satır görebilecek binden fazla satır içeren bir görünüm için karmaşık bir plan gibi görünüyor. Ancak aşağıdaki diğer gözlemlerle daha da kötüleşir:
- İç içe görünümler belirleyici değildir, bu nedenle bunları dizine ekleyemeyiz
- Her görünüm
UDF, dizeleri oluşturmak için birden fazla s'ye başvurur - Her UDF,
UDFyerelleştirilmiş diller için ISO kodlarını almak üzere iç içe geçmiş s içerir - Yığındaki Gösterim ilave kullanan dönen dize güçlendiriciler
UDFolarak sJOINyüklemleri - Her görünüm yığını tablo olarak kabul edilir, yani her birinde temel tablolara yazmak için
INSERT/UPDATE/DELETEtetikleyicileri vardır - Görünümlerde Bu tetikleyiciler kullanan
CURSORSbuEXEColan daha bu dizi yapı referans saklı yordamlarUDFs.
Bu benim için oldukça çürük görünüyor, ama TSQL ile sadece birkaç yıllık tecrübem var. Daha da iyi oluyor!
Bunun harika bir fikir olduğuna karar veren geliştirici, tüm bunları yaptı, böylece depolanan birkaç yüz dizenin UDFşemaya özgü bir dizeden dönen bir çeviriye sahip olabileceği anlaşılıyor.
İşte yığındaki görünümlerden biri, ama hepsi aynı derecede kötü:
CREATE VIEW [UserWKStringI18N]
AS
SELECT b.WKType, b.WKIndex
, CASE
WHEN ISNULL(il.I18NID, N'') = N''
THEN id.I18NString
ELSE il.I18nString
END AS WKString
,CASE
WHEN ISNULL(il.I18NID, N'') = N''
THEN id.IETFLangCode
ELSE il.IETFLangCode
END AS IETFLangCode
,dbo.User3StringI18N_KeyValue(b.WKType, b.WKIndex, N'WKS') AS I18NID
,dbo.UserI18N_Session_Locale_Key() AS IETFSessionLangCode
,dbo.UserI18N_Database_Locale_Key() AS IETFDatabaseLangCode
FROM UserWKStringBASE b
LEFT OUTER JOIN User3StringI18N il
ON (
il.I18NID = dbo.User3StringI18N_KeyValue(b.WKType, b.WKIndex, N'WKS')
AND il.IETFLangCode = dbo.UserI18N_Session_Locale_Key()
)
LEFT OUTER JOIN User3StringI18N id
ON (
id.I18NID = dbo.User3StringI18N_KeyValue(b.WKType, b.WKIndex,N'WKS')
AND id.IETFLangCode = dbo.UserI18N_Database_Locale_Key()
)
GO
İşte bu yüzden UDFs JOINtahmin olarak kullanılıyor . I18NIDKolon birleştirilmesiyle oluşturulur:STRING + [ + ID + | + ID + ]
Bunları test SELECTederken, görünümden bir basit ~ 309 satır döndürür ve yürütülmesi 900-1400ms alır. Dizeleri başka bir tabloya döküp üzerine bir dizin eklersem, aynı seçim 20-75 ms içinde döner.
Yani, uzun lafın kısası ben bir iyiliksever ve olmak istiyorum (ve ben bu sillyness bazılarını takdir umut) yeniden tasarımı ve do bu ürünü çalıştıran müşterilerin% 99 için yeniden yazma bu değil all herhangi yerelleştirme kullanmak -end kullanıcıların [en-US]İngilizce 2. / 3. dil olsa bile yerel ayarları kullanmaları beklenir .
Bu gayri resmi bir saldırı olduğu için aşağıdakileri düşünüyorum:
- Orijinal temel tablolardan temiz bir şekilde birleştirilmiş veri kümesiyle doldurulmuş yeni bir Dize tablosu oluşturun
- Tabloyu indeksleyin.
- Üst düzey içerir yığınında kez bir yedek kümesi oluşturma
NVARCHARveINTsütunlarınWKTypeveWKIndexsütunlar. UDFBazı birleşim öngörülerinde tür dönüşümlerini önlemek için bu görünümlere başvuran bir avuç değişiklik yapın (en büyük denetim tablomuz 500-2.000 milyon satırdır ve sütunu ( ) birleştirmek için kullanılanINTbirNVARCHAR(4000)sütunda depolar .)WKIndexINT- Görüşler
- Görünümlere birkaç dizin ekleyin
- İmleçler yerine set mantığı kullanarak görünümlerdeki tetikleyicileri yeniden oluşturma
Şimdi, asıl sorularım:
- Bir görünüm aracılığıyla yerelleştirilmiş dizeleri işlemek için en iyi uygulama yöntemi var mı?
UDFBir saplama olarak kullanmak için hangi alternatifler var ? (VIEWHer şema sahibi için belirli bir yazı yazabilir ve çeşitliUDFsaplamalara güvenmek yerine dili sabit kodlayabilirim .)- Bu görünümler iç içe
UDFgeçmişleri tam olarak niteleyip sonra görünüm yığınlarını şematik olarak belirleyerek basitçe deterministik hale getirilebilir mi?




UDF. Ayrıca, T-SQL Kullanıcı Tanımlı İşlevlere bakın: iyi, kötü ve çirkin