Ich habe eine SQL Server 2012-Datenbank, mit der ich Daten aus verarbeiteten Dateien speichere. Wir lesen Daten aus einem Ordner, verarbeiten sie mit Python und speichern die Ergebnisse in der Datenbank.
Eines der ersten Dinge, die wir in unserem ETL-Prozess tun, ist zu überprüfen, ob die Datei bereits verarbeitet wurde. Wir machen einfach ein:
SELECT id FROM table1 WHERE basename = <basename>
Wenn es ein Ergebnis gibt, überspringen wir die Datei, wenn es kein Ergebnis gibt, verarbeiten wir die Datei. Im Moment dauert diese Abfrage ~ 250ms mit ~ 5m Datensätzen. Wir haben bereits einen nicht gruppierten Index für die basename
Spalte.
Wir werden ungefähr 100-200.000 Datensätze pro Monat hinzufügen. Wir bekommen die Dateien in Stapeln. Wir sehen also möglicherweise 2k-Dateien und 2 Stunden später weitere 2k-Dateien. An manchen Tagen erhalten wir 10.000 Dateien, an anderen Tagen erhalten wir möglicherweise nur 4.000 Dateien.
Wenn alle anderen Variablen gleich bleiben, gibt es eine Faustregel für die Projektion, wenn bei dieser Abfrage Leistungsprobleme auftreten (Abfragen, die länger als 1 Sekunde dauern), außer 15 bis 20 Millionen Datensätze in die Tabelle einzufügen und zu sehen, was passiert?
Tabelle DDL:
CREATE TABLE [dbo].[raw_records](
[id] [int] IDENTITY(1,1) NOT NULL,
[basename] [varchar](512) NULL,
[filename] [varchar](1024) NULL,
[file_size] [int] NULL,
[machine] [varchar](10) NULL,
[insert_timestamp] [datetime] NULL,
[raw_xml] [xml] NULL,
[process_status] [varchar](2048) NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Index:
CREATE NONCLUSTERED INDEX [basename_index] ON [dbo].[raw_records]
(
[basename] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Diese Tabelle wurde lange vor Beginn meiner Arbeit erstellt. Ich gehe also davon aus, dass jemand gerade die filename
maximale Länge von 1024 festgelegt hat, um "genug" zu halten. Sicher veränderbar.
Die erstellten Dateien haben einen Zeitstempel und eindeutige Informationen im Dateinamen selbst (z. B. system1_metadata_timestamp.xml
) ein "System" konnte (oder sollte) niemals eine Datei mit demselben Zeitstempel erstellen.
select max(len(basename)), max(len(filename)) from dbo.raw_records;
Rückgabe: basename
- 143, filename
- 168. Wahrscheinlich eine gute Sache, um auf maximal 260 zu wechseln.
process_status
Wahrscheinlich muss es auch nicht so lange dauern, aber ich halte es für vernünftig, dies zu erraten, da die Spalte Fehlermeldungen aus der Verarbeitungsphase enthält. Ich habe eine Abfrage ausgeführt und hatte maximal 600 Zeichen. Wir fragen diese Spalte jedoch normalerweise nicht ab. Es ist nur informativer für das Debuggen.
Ich gehe die Anwendung durch, um solche Sachen aufzuräumen. An bestimmten Stellen komme ich nicht davon weg, aber an anderen kann ich leider nicht viel dagegen tun (z. B. muss die XML-Spalte tatsächlich abgerufen werden, um Daten daraus zu extrahieren). Diese Frage ergab sich einfach daraus, dass ich die Leistung der fraglichen Abfrage gesehen habe und nicht wollte, dass sie mir entgeht. Es ist das erste, was für jede Datei ausgeführt wird. Wenn dies nicht funktioniert, wird auch nichts anderes ausgeführt.