ETL DB aktuell halten

ukulele

Datenbank-Guru
Beiträge
5.306
Ich habe immer noch mein Bastelprojekt. Es werden mehrere Datenquellen per linked server angezapft, aber ich kann eben nur lesen und habe keine Möglichkeit in die DB einzugreifen. Performance ist nicht so geil aber ich muss mitunter häufig auf möglichst aktuelle Daten zugreifen.

Ich kann alles in eine Auswertungs-DB schaufeln aber wenn ich dann z.B. alle 2 Minuten alle Datensätze hole (SELECT oder MERGE), abgleiche und weiter verarbeite dann wird das beiden Datenbanken nicht gut tun. Änderungen per Trigger erkennen ist aber halt nicht drin. Gibt es noch irgendeine elgante Form sowas wie eine Schattenkopie, einen Mirror oder sonstwas zu erstellen nur mit Leserechten auf dem Quell-System?

Zielsystem ist MSSQL 2022 mit Standard Lizenz.
 
Werbung:
Ich weiß nicht, was MSSQL alles kann.
Was mir dazu als Standard einfällt: Materialized Views
Ein MView auf der eigenen Seite, der einfach nur geradeaus alle Daten aus einer Remotetabelle saugt.
Und dann hoffentlich schnallt, dass er nur Änderungen rüberziehen muss.

Ansonsten ein logischer Ansatz, der Intimkenntnis des Änderungsverhaltens der Remotetabelle voraussetzt.
Werden einfach nur Datensätze angefügt? (z.B. Buchungen)
Werden alle Daten immer wieder verändert (z.B. Lagerhaltung)
Gibt es Indikatorfelder (z.B. Änderungsdatum), die man beim Abgleich nutzen kann?

Daraus kann man sich vielleicht einen smarten Mechanismus basteln, grob nur das nötigste rüber zu holen.
- letzte ID vom letzen Lauf
- letzte Datumswerte
- ..
 
Materialized Views auf Verbindungsserver gehen leider nicht, damit wollte ich auch schon expirimentieren.

Die wichtigste Remote-DB ist DATEV eodb, nicht mal die DATEV scheint so wirklich gut zu wissen was dort passiert aber in einigen Fällen habe ich tatsächlich Buchungstabellen. Leider können sich auch dort Datensätze ändern, wenn auch recht selten.

Wie könnte man die Laufzeit eines Selects in eine Log Tabelle schreiben?
 
Ich würde das per command line machen (oder scheduled task).
timer aktivieren, gesamten output loggen.

sqlcmd -i script.sql -o output.log -S myserver -E -d mydb

Wenn es um das Selektieren großer Datenmengen geht (oder um die Zeit zu stoppen) wäre es vielleicht besser, ein Script zu verwenden, dass die Ergebnisse direkt in einer Datei versenkt oder sogar nach /dev/null, Du willst ja vermutlich nur die Zeit stoppen.
 
Meine Idee ist derzeit eine SP zu bauen die wie ein Select die Daten zurück liefert. Die Daten sollen aus einer Kopie in der ETL DB kommen und durch die SP aus der Produktiv DB aktualisiert werden (eventuell schon vor dem ersten Select, mal sehen). Die SP soll aber die Daten nicht immer aktuallisieren sondern es soll sowas wie einen cooldown geben, sprich ich prüfe zuvor, wann die Daten das letzte mal geholt wurden.

Zum Zeitstempel, wann das letzte mal synchronisiert wurde, soll zusätzlich berücksichtigt werden wie lange der letzte Vorgang gelaufen ist. Dafür interessiert mich die Laufzeit, aber ich kann natürlich für den Vorgang auch die Differenz aus zwei Zeitstempeln nehmen. Ich kann dann auch loggen wie lange der Vorgang dauert und wann er besonders häufig initialisiert wird.

Und natrlich betrifft das nicht alle Daten, einige reichen wirklich Tagesaktuell.
 
Ich dachte, mit der Messung willst Du vielleicht mal über 24h oder 7d fühlen, wann der remote sowieso rumidled.
"Zuhause" kannst Du natürlich alles machen was Du magst, ein paar Metadaten zum eigenen Status zu sammeln, tut ja niemand weh.

Bei sowas geht es m.E. auch um Transparenz bzw. Bedarf. Wenn Du die Sachlage vermittelst und entsprechend den Bedarf klärst (an Aktualität- kann bei DATEV jetzt nicht um 12h gehen...) und an die Ergebnisse dran schreibst, wie alt die sind, dann kann man sicher gut auf 80:20 kommen oder besser, Hauptsache, minimaler Aufwand (an Arbeit und Ressourcen).
 
Aktuell mache ich das so (auch über Linked Server), initial alles holen und dann im Intervall nur was neu dazu gekommen ist. Geht natürlich nur mit passenden Zeitstempel und wieviele Daten in zwei Minuten (bei Dir) dort auflaufen.
 
Die Menge an neuen Daten ist lächerlich wenig. Aber Änderungen an Bestandsdaten kann ich in einigen Fällen nur durch einen Abgleich erkennen. Es gibt sogar eine wichtige Tabelle ohne PK, da kann sich die Reihenfolge ändern.

Ich brauche halt nur einige Daten eigentlich live. Aber natürlich nur wenn ein Benutzer sie auch anfragt und nicht einfach stumpf jede Minute.
 
Jetzt habe ich mir was tolles ausgedacht und hab mich selbst ausgetrickst :-)

Ich habe eine SP die
a) Daten aus einer lokalen Tabelle zurück gibt und
b) die Daten in eben dieser Tabelle im Anschluss aktualisiert (falls nicht innerhalb einer definierten Zeitspanne bereits aktualisiert wurde).

Das scheint soweit "ganz gut" zu funktionieren, ich wollte das testen. Die Idee ist das mein Frontend (in diesem Fall PowerBI) die Daten aufruft und damit im Hintergrund die Aktuallisierung irgendwie triggern kann, vielleicht auch gezielt. Da es keinen Trigger auf Selects gibt bin ich den Weg der SP gegangen. Leider kann ich aber die SP gar nicht per View oder Join auslösen, auch wenn sie eine Tabelle zurück gibt. Mein Frontend erwartet natürlich Tabellen oder Sichten...
 
Ich habe aktuell mehrere Prozeduren um meine Tabellen aktuell zu halten, eine pro Tabelle. Struktur ist eigentlich simpel:
Code:
BEGIN TRANSACTION
INSERT (Datensätze, die es noch nicht gibt)
DELETE (Datensätze, die es nicht mehr gibt)
UPDATE (Datensätze mit Änderungen
COMMIT TRANSACTION
Laufzeit 17 Sekunden. Das mit der Transation war eigentlich aus einem anderen Grund noch drin, das wäre eigentlich nicht nötig, Laufzeit ohne liegt bei 16 Sekunden. Jetzt hat die Zieltabelle gelegentlich einen oder mehrere Indexe, auch clustered. Ich überlege, die zu deaktivieren, wenn ich allerdings
Code:
ALTER INDEX ALL ON [tabelle] DISABLE;
...
ALTER INDEX ALL ON [tabelle] REBUILD;
einbaue erhalte ich:
Warnung: Der ...-Index für das Tabelle-Objekt "..." wurde deaktiviert, weil der gruppierte Index für das Tabelle-Objekt deaktiviert wurde.
Was wäre das richtige vorgehen? Wäre das überhaupt sinnvoll? Der INSERT profitiert ja beim Abgleich auch vom Index weil nicht alles eingefügt wird.

Leider ist das jetzt nur eine Tabelle und noch nicht mal die Größte. Das ganze wird sehr oft laufen.
 
Werbung:
Zurück
Oben