Leistungsaspekt: ​​Spread Zeilen in mehreren Tabellen vs konzentriert alle Zeilen in einer Tabelle

StackOverflow https://stackoverflow.com/questions/1142296

Frage

Leistungsaspekt:. Verteilen Zeilen in mehreren Tabellen vs Konzentrat aller Zeilen in einer Tabelle

Hallo.

Ich brauche Informationen über über jeden Schritt zu protokollieren, die in einer SQL-DB in der Anwendung geht weiter. Es gibt bestimmte Tabellen, ich will das Protokoll in Beziehung gesetzt werden sollte: Produkt - einbucht, wenn ein Produkt erstellt wurde geändert usw. Auftrag - wie oben Versand - same etc. etc. etc.

Die Daten werden müssen werden oft abgerufen werden.

Ich habe einige Ideen, wie man es tun:

  1. eine Log-Tabelle, die Spalten für alle diese Tabellen enthalten wird, dann, wenn ich für eine bestimmte Produkt wollen Daten in der Benutzeroberfläche darstellen wählen Sie * aus Log wo LogId = Product.ProductID. Ich weiß, dass dies lustig sein könnte viele cols haben, aber ich habe das Gefühl, dass die Leistung besser wird. In der anderen Seite gibt es eine riesige Menge an Zeilen in dieser Tabelle sein.
  2. viele Protokolltabellen für jeden Protokolltyp haben (ProductLogs, OrderLogs etc.) Ich mag diese Idee nicht wirklich, da es nicht im Einklang ist und haben viele Tabellen mit derselben Struktur ist nicht sinnvoll, aber (?), Es könnte sein, schneller, wenn in einer Tabelle zu suchen, die eine geringere Menge an Zeilen (mi falsch?) hat.
  3. Nach Aussage nicht. 1, I könnte eine zweite many-to-one Tabelle tun, die LogId, TableNameId und RowId cols haben wird, und wird eine Protokoll Zeile in viele Tabellenzeilen in der DB verweisen, als ein UDF haben, um Daten abzurufen (beispielsweise Protokoll-ID 234 gehört zur Tabelle Kunden bei CustomerId 345 und Product-Tabelle, wo productId = RowId); Ich denke, dass dies die schönste Art und Weise ist, es zu tun, aber auch hier könnte es eine riesige Menge von Zeilen sein, wird es die Suche verlangsamen? oder das ist, wie es getan werden sollte, whatcha sagen? ...

Beispiel Nr 3 in der obigen Liste:

CREATE TABLE [dbo].[Log](
    [LogId] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [Description] [varchar](1024) NOT NULL,
 CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Log]  WITH CHECK ADD  CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
    [LogId] [int] NOT NULL,
    [TableName] [varchar](32) NOT NULL,
    [RowId] [int] NOT NULL,
 CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC,
    [TableName] ASC,
    [RowId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[LogReference]  WITH CHECK ADD  CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(   
    @TableName varchar(32),
    @RowId int
)
RETURNS 
@Log TABLE
(       
    LogId int not null,
    UserId int not null,
    Description varchar(1024) not null
)
AS
BEGIN

INSERT INTO @Log
SELECT     [Log].LogId, [Log].UserId, [Log].Description
FROM         [Log] INNER JOIN
                      LogReference ON [Log].LogId = LogReference.LogId
WHERE     (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
    RETURN 
END
GO
War es hilfreich?

Lösung

Ich würde auf jeden Fall für die Option 3, aus mehreren Gründen gehen:

Die Daten in den Feldern einer Tabelle sein sollten, nicht als Tabellenname (Option 2) oder einen Feldname (Option 1). Auf diese Weise die Datenbank wird einfacher, mit zu arbeiten und leichter zu pflegen.

Engere Tabellen genrally besser. Die Anzahl der Zeilen hat weniger Einfluss auf die Leistung als die Anzahl der Felder.

Wenn Sie ein Feld für jede Tabelle (Option 1) haben, werden Sie wahrscheinlich viele leere Felder erhalten, wenn nur einige der Tabellen, die von einer Operation betroffen sind.

Andere Tipps

Seien Sie vorsichtig mit preoptimizing Datenbanken. Die meisten Datenbanken sind ziemlich schnell und etwas kompliziert. Sie wollen zunächst einen Test für die Effizienz auszuführen.

Second alles in einer Tabelle setzen macht es wahrscheinlicher, dass die Ergebnisse, die Sie im Cache wollen die Leistung beschleunigen wird immens. Leider macht es auch es viel wahrscheinlicher, dass Sie einen riesigen Tisch zu suchen haben zu finden, was Sie suchen. Dies kann zum Teil mit einem Index gelöst werden, aber keinen Indizes kommen frei (sie machen das Schreiben teurer, für eine Person).

Mein Rat wäre, einen Test, um zu sehen, ob die Leistung wirklich die verschiedene Szenarien Materie und dann testen, um zu sehen, welche die schnellsten ist.

Wenn Sie große Datenmengen zu sprechen sind (Millionen von Zeilen +), dann werden Sie einen Vorteil erhalten haben von der Verwendung verschiedene Tabellen sie speichern in.

z. Grund Beispiel 50 Millionen Log-Einträge, unter der Annahme, 5 verschiedene „Typen“ von Log-Tabelle Besser hat 5 x 10 Millionen Zeilen Tabellen als 1 x 50 Millionen Zeilen Tabelle

  • INSERT Leistung wird mit einzelnen Tabellen besser - Indizes für jede Tabelle kleiner sein wird und so schneller / leichter als Teil des Einsatzes Operation aktualisiert / aufrechterhalten werden

  • READ Leistung wird besser mit einzelnen Tabellen - weniger Daten abzufragen, kleinerem Indizes zu durchqueren. Auch klingt wie Sie eine zusätzliche Spalte zu speichern brauchen würden, um festzustellen, welche Art von Protokolleintrag ein Datensatz ist (Artikel, Versand ....)

  • MAINTENANCE auf kleinere Tabellen ist weniger schmerzhaft (Statistiken, Index Defragmentierung / Wiederaufbau usw.)

Im Wesentlichen ist das über Partitionierungsdaten. Von SQL 2005 wird es gebaut hat Unterstützung für die Partitionierung (siehe hier ), aber Sie müssen für die Enterprise Edition, die Sie im Grunde ermöglicht es, Daten in einer Tabelle zu partitionieren Leistung zu verbessern (zB Sie eine Log-Tabelle haben würde, und dann festlegen, wie die Daten innerhalb dieses partitioniert)

hörte ich ein Interview mit einem der eBay Architekten vor kurzem, der die Bedeutung der Partitionierung betonte, wenn Leistung und Skalierbarkeit benötigen, und ich stimme auf Grund meiner Erfahrungen.

Versuchen Sie, Ihre Datenzugriffsschicht in einer Art und Weise zu implementieren, so dass Sie von einem Datenbankmodell zu einem anderen, wenn nötig ändern -. Sie können nur eine später zu Auswirkungen auf die Leistung auswählen und Sorge

Ohne einige Performance-Tests zu tun ist und eine genaue Vorstellung von den möglichen laden Sie Ihre seinen Gang bringen wird schwierig sein, zu optimieren, wie die Leistung von einer Reihe von Faktoren ab, wie zum Beispiel die Anzahl der liest, die Anzahl der Schreibvorgänge und ob die Lese- und Schreibvorgänge sind wahrscheinlich zu Konflikten und Ursache Verriegelung.

Meine Präferenz für die Option 1 btw wäre -. Einfachsten eine Reihe von Verbesserungen zu tun, und es gibt Sie aus verschiedenen Arten von Problemen beheben zu helfen, tun kann, haben Sie vielleicht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top