AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Firebird Insert

Ein Thema von lxo · begonnen am 29. Okt 2020 · letzter Beitrag vom 17. Nov 2020
Antwort Antwort
lxo

Registriert seit: 30. Nov 2017
130 Beiträge
 
Delphi 10.4 Sydney
 
#1

Firebird Insert

  Alt 29. Okt 2020, 09:12
Datenbank: Firebird • Version: 3.0.7 • Zugriff über: -
Hallo,

ich hab eine Prozedur in Firebird geschrieben um Datensätze zu kopieren.
In dem Fall wären es Anzeigeoptionen für Wirkstoffe.
Diese kann man mit der Prozedur von einem Werk in ein anderes kopieren.

Das geht schon relativ schnell ca. 20.000-25.000 Inserts pro Sekunde.

Meine Frage, könnte man das noch optimieren bzw. noch schneller machen.
Hat da jemand eine Idee?

Code:
  procedure KOPIERE_ANZEIGEOPTIONEN ( X_QUELLE_WIRKSTOFF type of column WIRK_ANZEIGEOPTIONEN.WIRKSTOFF,
                                            X_ZIEL_WIRKSTOFF type of column WIRK_ANZEIGEOPTIONEN.WIRKSTOFF,
                                            X_QUELLE_WERKNR type of column WIRK_ANZEIGEOPTIONEN.WERKNR,
                                            X_ZIEL_WERKNR type of column WIRK_ANZEIGEOPTIONEN.WERKNR)
  as
  begin
    delete from WIRK_ANZEIGEOPTIONEN WA
    where WA.WIRKSTOFF = :X_ZIEL_WIRKSTOFF and
          WA.WERKNR = :X_ZIEL_WERKNR;

    insert into WIRK_ANZEIGEOPTIONEN (WERKNR, WIRKSTOFF, ANZEIGE, DRUCK)
    select :X_ZIEL_WERKNR, :X_ZIEL_WIRKSTOFF, WA.ANZEIGE, WA.DRUCK
    from WIRK_TIERART WA
    where WA.WIRKSTOFF = :X_QUELLE_WIRKSTOFF and
          WA.WERKNR = :X_QUELLE_WERKNR;
  end
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
7.961 Beiträge
 
Delphi XE4 Professional
 
#2

AW: Firebird Insert

  Alt 29. Okt 2020, 10:14
Hallo,
1. die Indizes von WIRK_ANZEIGEOPTIONEN temporär deaktivieren (Alter Index)
2. Das Select dahingehend prüfen, ob Indizes benutzt werden
3. Backup/Restore, um die DB optimal aufzubauen

Das 3. ist aber eigentlich nicht notwendig.
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von IBExpert
IBExpert

Registriert seit: 15. Mär 2005
517 Beiträge
 
FreePascal / Lazarus
 
#3

AW: Firebird Insert

  Alt 29. Okt 2020, 12:44
auf jeden fall drauf achten das da keine alten transaktionen auf der db offen sind, weil du damit sonst bei den deletes immer nur recordversionen erzeugst
und ganz wichtig auf der tabelle in der du schreibst auch keine unnötigen indizes haben, möglichst keine unnötig langen varchar deklarationen usw

mit ca 25000 pro sekunde ist das aber schon klagen auf hohem nieveau

Hardwarespeed mal über ibexpert benchmark messen ist sicherlich auch ein hinweis
Holger Klemt
www.ibexpert.com - IBExpert GmbH
Oldenburger Str 233 - 26203 Wardenburg - Germany
IBExpert and Firebird Power Workshops jederzeit auch als Firmenschulung
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
130 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Firebird Insert

  Alt 29. Okt 2020, 13:04
Danke für die Rückmeldungen.
Extra Indizes hab ich für die Tabelle jetzt nicht, nur ein Primärschlüssel und zwei Fremdschlüssel.

Ich bin auch soweit zufrieden mit dem Ergebnis, dachte nur vielleicht gibt es da noch Tipps und Tricks da noch etwas herauszukitzeln.

Das Kopieren direkt mit Firebird im Gegensatz, vorher über Delphi schon um das ca. 400-fache schneller geworden.

Geändert von lxo (29. Okt 2020 um 13:11 Uhr)
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
505 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Firebird Insert

  Alt 30. Okt 2020, 15:29
Anstatt den Datensatz in der Zieltabelle erst zu suchen, dann zu löschen und dann Insert zu machen könnte man ev. auch Update or Insert machen.
Ob das schneller ist kann ich aber nicht sagen.
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
130 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Firebird Insert

  Alt 16. Nov 2020, 15:12
Ich bräuchte nochmal eure Hilfe, an sich funktioniert das alles ganz gut mit der Kopier-Prozedur bei Datenbanken mit mehreren Millionen-Datensätzen ist das aber ganz schön langsam alles zu löschen und neu anzulegen für ein Werk.

Alle Wirkstoffe kopieren von ein Werk ins andere wäre aktuell so.
Code:
  procedure KOPIERE_ANZEIGEOPTIONEN ( X_QUELLE_WERKNR type of column WIRK_ANZEIGEOPTIONEN.WERKNR,
                                            X_ZIEL_WERKNR type of column WIRK_ANZEIGEOPTIONEN.WERKNR)
  as
  begin
    delete from WIRK_ANZEIGEOPTIONEN WA
    where WA.WERKNR = :X_ZIEL_WERKNR;

    insert into WIRK_ANZEIGEOPTIONEN (WERKNR, WIRKSTOFF, ANZEIGE, DRUCK)
    select :X_ZIEL_WERKNR, :X_ZIEL_WIRKSTOFF, WA.ANZEIGE, WA.DRUCK
    from WIRK_TIERART WA
    where WA.WIRKSTOFF = :X_QUELLE_WIRKSTOFF and
          WA.WERKNR = :X_QUELLE_WERKNR;
  end


Ich habe mir gedacht das es doch effizienter sein sollte wenn ich nur die Wirkstoffe lösche die es in der Quelle nicht gibt.
Da habe ich dann an "Update or Insert" oder "Merge Into" gedacht ich schaffe es damit jedenfalls alle nötigen Datensätze zu aktualisieren und ggf. fehlende hinzuzufügen.
Schaffe es aber nicht alle nicht mehr nötigen aus dem Ziel zu löschen.

Was ich genau erreichen möchte:
Alle Anzeigeoptionen von Werk 1 nach Werk 2 kopieren.
Alle bisherigen Einträge für Werk 2 sollen überschrieben werden.
Daher ...
- bei Datensätzen die zusammenpassen ein Update.
- bei Datensätzen die im Ziel nicht gefunden werden Insert
- bei Datensätzen die in der Quelle nicht gefunden werden delete.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
1.751 Beiträge
 
Delphi 7 Professional
 
#7

AW: Firebird Insert

  Alt 16. Nov 2020, 17:16
Gehe mal davon aus, dass WERKNR, WIRKSTOFF einen eindeutigen Wert darstellen.

Mit etwas in der Art könnte dann das Löschen etwas einfacher werden:
SQL-Code:
delete from Tabelle_Werk2 w2
where not exists (
  select 1 from Tabelle_Werk1 w1
  where w1.WERKNR = w2.WERKNR
  and w1.WIRKSTOFF = w2.WIRKSTOFF
)
Du brauchst aber immer zwei Statements, das für's Insert bzw. Update und das zum Löschen. Eine Möglichkeit, dies alles in einem Statement umzusetzen, ist mir nicht bekannt.
  Mit Zitat antworten Zitat
lxo

Registriert seit: 30. Nov 2017
130 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Firebird Insert

  Alt 17. Nov 2020, 07:35
Gehe mal davon aus, dass WERKNR, WIRKSTOFF einen eindeutigen Wert darstellen.

Mit etwas in der Art könnte dann das Löschen etwas einfacher werden:
SQL-Code:
delete from Tabelle_Werk2 w2
where not exists (
  select 1 from Tabelle_Werk1 w1
  where w1.WERKNR = w2.WERKNR
  and w1.WIRKSTOFF = w2.WIRKSTOFF
)
Du brauchst aber immer zwei Statements, das für's Insert bzw. Update und das zum Löschen. Eine Möglichkeit, dies alles in einem Statement umzusetzen, ist mir nicht bekannt.
Bei meiner Recherche bin ich darauf gestoßen, dass es z.B. bei MSSQL "merge when not matched by source"gibt.
Nur leider gibt es das bei Firebird nicht und soll wohl auch nicht implementiert werden. http://tracker.firebirdsql.org/browse/CORE-2515

Ich habe in einem Forum dafür trotzdem eine gute Lösung gefunden.
https://www.sql.ru/forum/1323218/mer...ched-by-source

Ich habe beim "Firbird tracker" ein Ticket zu dem Thema nochmal angelegt. Für alle die es vielleicht interessiert.
http://tracker.firebirdsql.org/browse/CORE-6448

Geändert von lxo (17. Nov 2020 um 08:00 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 15:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf