Ich entwerfe eine Multi-Modul C#/SQL Server-basierte Anwendung. Mein Entwurf ist, alle allgemeinen Nachschlagenwerte in einer Tabelle zu halten, die KeyTypeValues
genannt wird. Diese Tabelle bezieht sich auf KeyTypes
, die definiert, um welche Art von Daten es sich handelt.Problematische Datenbank-Design verursacht Leistungsprobleme
Zum Beispiel:
oms.KeyTypes
------------
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY
KeyTypeName VARCHAR(40) NOT NULL
...
oms.KeyTypeValues
-----------------
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY
KeyTypeId INT NOT NULL (FOREIGN KEY to oms.KeyTypes Id)
KeyTypeValueMeaning VARCHAR(80) NOT NULL
...
oms.KeyTypes Beispieldaten:
Id KeyTypeName KeyTypeDescription
-- ----------- ------------------
1 RES_MFGS Resource Manufacturers
2 RES_OWNERSHIP_TYPES Resource Ownership Types
...
oms.KeyTypeValues Daten Beispiel:
Id KeyTypeId KeyTypeValueMeaning
-- --------- -------------------
1 1 Ford
2 1 Chevrolet
3 2 Owned
4 2 Leased
...
So ist die Idee, dass ich nicht habe um separate Manufacturers
, OwnershipType
, Model
usw. etc. Tabellen zu erstellen, wie wir benötigen keine weiteren Informationen über diese Werte außer ihrem Wert. Momentan habe ich etwa 88 bereits definiert und das Design hat bei mir gut funktioniert.
Ich arbeite an einer Problemabfrage, die mir Leistungsprobleme beim Beitritt aus einer Tabelle mit dem Namen res.ResourceItems
. Ich muss 6 Mal für verschiedene Lookups auf die KeyTypeValues
Tabelle zugreifen.
Teil ResourceItems
Definition:
res.ResourceItems
-----------------
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY
OwnsershipTypeId INT NOT NULL
ManufacturerId INT NOT NULL
...
Wenn ich mein Problem Schlüsselart (RES_OWNERSHIP_TYPES
) zu beseitigen, kann ich es laufen weit offen, und es zieht sich zurück ~ 112.000 Zeilen mit mehr als 70 Spalten in etwa 17 Sekunden. Die Leistung ist nicht fantastisch, aber wenn man bedenkt, dass ich mich an 9 zusätzliche Tische anschließen muss, ist das akzeptabel. Wenn ich jedoch die Verknüpfung zum Abrufen von RES_OWNERSHIP_TYPES
hinzufüge, springt die Ausführungszeit auf 45 Sekunden. Der Schlüsseltyp RES_OWNERSHIP_TYPES
hat nur 3 mögliche Werte an diesem Punkt und oms.KeyTypeValues
hat nur etwa 3.000 Datensätze insgesamt. Es wird im Laufe der Zeit weiter langsam wachsen, da wir dem System, das gebaut wird, mehr hinzufügen.
Ich weiß, dass das Ziehen von Besitztypen und das Erstellen einer enum
stattdessen eine effizientere Möglichkeit wäre, dies zu handhaben, da es unwahrscheinlich ist, dass wir mehr Eigentumsarten haben werden; Ich bin jedoch besorgt über das Gesamtdesign, wo solch ein dramatischer Leistungseinbruch stattfindet.
Ich habe Fremdschlüsselbeziehungen von res.ResourceItems
bis oms.KeyTypeValues
für alle Id-Werte. Ich habe auch Non-Unique, Non-Clustered-Index-Setup auf oms.KeyTypeValues.Id
Spalte. Ich habe sie neu aufgebaut, um die Fragmentierung zu beseitigen.
Als Test, habe ich getrennte KeyTypes
und KeyTypeValues
Tabellen in meinem res
Schema und geladen nur mit RES_OWNERSHIP_TYPES
Werten und trat zu ihm, und der Ausführungszeit auf etwa 17 Sekunden ging zurück. Ich würde das lieber nicht ausführen, da es meine Absicht besiegt und ein großes Problem zu lösen scheint.
Ich kann nicht feststellen, warum es so einen großen Hit nur mit diesem Join gibt und hoffte, dass jemand Einblick in das haben könnte, was ich übersehen könnte. Ich werde gerne mehr von der Datenbank-Design teilen, wenn nötig.
Verwenden Sie [Indizes abdecken] (http://www.dbadiaries.com/sql-server-covering-index-and-key-lookup/). Beachten Sie, dass SQL Server 2005 und höhere Versionen [enthaltene Spalten] (http://msdn.microsoft.com/en-us/library/ms190806.aspx) sowie zusammengesetzte Indizes unterstützen. – HABO