Beim Erstellen eines Datenbankprofils bin ich auf eine Ansicht gestoßen , die auf einige nicht deterministische Funktionen verweist, auf die für jede Verbindung im Pool dieser Anwendung 1000 bis 2500 Mal pro Minute zugegriffen wird . Eine einfache SELECT
Ansicht ergibt den folgenden Ausführungsplan:
Dies scheint ein komplexer Plan für eine Ansicht mit weniger als tausend Zeilen zu sein, in denen sich möglicherweise alle paar Monate eine oder zwei Zeilen ändern. Bei folgenden anderen Beobachtungen wird es jedoch noch schlimmer:
- Verschachtelte Ansichten sind nicht deterministisch, daher können wir sie nicht indizieren
- Jede Ansicht verweist auf mehrere
UDF
s, um die Zeichenfolgen zu erstellen - Jede UDF enthält verschachtelte
UDF
s, um die ISO-Codes für lokalisierte Sprachen abzurufen - Ansichten im Stapel verwenden zusätzliche String-Builder, die von
UDF
s alsJOIN
Prädikate zurückgegeben werden - Jede Ansicht Stapel wird als Tabelle behandelt, was bedeutet , dass es
INSERT
/UPDATE
/DELETE
Trigger für jede zu schreiben , um die zugrunde liegenden Tabellen - Diese Auslöser in den Ansichten verwenden
CURSORS
dieEXEC
gespeicherten Prozeduren, die auf mehr dieser Zeichenfolgengebäude verweisenUDF
.
Dies scheint mir ziemlich faul zu sein, aber ich habe nur ein paar Jahre Erfahrung mit TSQL. Es wird auch besser!
Es scheint, dass der Entwickler, der dies für eine großartige Idee hielt, dies alles getan hat, damit die wenigen hundert gespeicherten Zeichenfolgen eine Übersetzung basierend auf einer Zeichenfolge haben können, die von einer schemaspezifischen zurückgegeben UDF
wird.
Hier ist eine der Ansichten im Stapel, aber sie sind alle gleich schlecht:
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
Hier ist, warum UDF
s als JOIN
Prädikate verwendet werden. Die I18NID
Spalte wird gebildet durch Verketten von:STRING + [ + ID + | + ID + ]
Während des Testens von diesen gibt eine einfache SELECT
Ansicht ~ 309 Zeilen zurück und benötigt 900-1400 ms, um ausgeführt zu werden. Wenn ich die Zeichenfolgen in eine andere Tabelle kopiere und einen Index darauf lege, wird dieselbe Auswahl in 20 bis 75 ms zurückgegeben.
So lange Geschichte kurz (und ich hoffe , dass Sie einige dieser sillyness geschätzt) ich ein guter Samariter und Re-Design und Re-write dies für die 99% der Kunden sein wollen dieses Produkt läuft die noch nicht jede Lokalisierung bei Nur- verwenden Es wird erwartet, dass Endbenutzer das [en-US]
Gebietsschema auch dann verwenden, wenn Englisch eine zweite / dritte Sprache ist.
Da dies ein inoffizieller Hack ist, denke ich an Folgendes:
- Erstellen Sie eine neue String-Tabelle, die mit einem sauber verknüpften Datensatz aus den ursprünglichen Basistabellen gefüllt ist
- Indizieren Sie die Tabelle.
- Erstellen Sie ein Ersatz - Set von Top-Level - Ansichten in dem Stapel , die einschließen
NVARCHAR
undINT
Spalten für dieWKType
undWKIndex
Spalten. - Ändern Sie eine Handvoll
UDF
s , die diese Ansichten zu vermeiden Typkonvertierungen in einigen Joinvergleichselemente verweisen (unsere größte Audit - Tabelle ist 500-2,000M Zeilen und speichert eineINT
in einerNVARCHAR(4000)
Spalte , die gegen die verbinden verwendet wirdWKIndex
Spalte (INT
).) - Schemabind die Ansichten
- Fügen Sie den Ansichten einige Indizes hinzu
- Erstellen Sie die Auslöser in den Ansichten mithilfe der festgelegten Logik anstelle der Cursor neu
Nun meine eigentlichen Fragen:
- Gibt es eine Best Practice-Methode, um lokalisierte Zeichenfolgen über eine Ansicht zu verarbeiten?
- Welche Alternativen gibt es für die Verwendung von a
UDF
als Stub? (Ich kannVIEW
für jeden Schemabesitzer ein spezifisches schreiben und die Sprache hart codieren, anstatt mich auf eine Vielzahl vonUDF
Stubs zu verlassen.) - Können diese Ansichten einfach deterministisch gemacht werden, indem die verschachtelten
UDF
s vollständig qualifiziert und dann die Ansichtsstapel schematisiert werden?
UDF
Definition. Beziehen Sie sich auch auf T-SQL Benutzerdefinierte Funktionen: Zwei glorreiche Halunken