Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Array in SQL (https://www.delphipraxis.net/189816-array-sql.html)

Jasocul 26. Jul 2016 06:41

Datenbank: MS-SQL-Server • Version: 2008 R2 • Zugriff über: stored procedure

Array in SQL
 
Hinweis auf Cross-Posting:
Enwickler-Ecke

Ja, ich weiß, dass es in SQL keine Arrays gibt.
Mein Problem ist folgendes:
Ich benötige eine Stored-Procedure, die ca. eine halbe Million Datensätze verarbeitet.
Darin enthalten sind verschiedenste String-Operationen, die auf zwei Tabellen (weniger als 50 Datensätze) zurückgreifen, um z.B. Zeichen- und Wort-Ersetzungen durchzuführen. Dies ist für jeden Datensatz der großen Tabelle erforderlich und muss jeden Tag einmal durchgeführt werden (Datenabgleich zwischen mehreren, unabhängigen Systemen).

Damit ich auf die kleinen Tabellen zurückgreifen kann, habe ich 2 Cursor mit Scroll-Option definiert. Diese beiden Cursor sind aber mein Flaschenhals und ich würde hier gerne optimieren. Ohne diese Cursor läuft die SP weniger als 30 Sekunden, mit den Cursor fast 10 Minuten. Alle anderen Operationen in der SP habe ich zum Test rausgenommen.

Ein Versuch, innerhalb der SP eine Tabelle zu deklarieren und diese als Basis zu nehmen, hat keinen Geschwindigkeitsvorteil gebracht. Ich vermute, das die Datenbank intern eine temporäre Tabelle dafür aufbaut und somit genauso arbeitet, als würde ich die echten Tabellen nutzen.

Theoretisch könnte ich mir eine Menge Variablen deklarieren und das ohne Tabellen machen, aber dann müsste ich bei jeder Änderung der Tabellen die SP anpassen.

Hat jemand eine Idee, wie das ganze optimiert werden kann?

rokli 26. Jul 2016 07:04

AW: Array in SQL
 
Moin Jasocul,

ich hatte vor einigen Wochen auch das Problem das große Datenmengen in Beziehung gesetzt werden mussten und die Verarbeitung elendig lange gedauert hat. War übrigens SQL2012

Im SQL Management Studio habe ich mir dann mal die Ausführungspläne angesehen, und der Ausführungsplan hat mir Empfehlungen für weitere Indices gegeben. Ich konnte durch den Einsatz eines ORDER(!) die Verarbeitungszeit drastisch senken ... von mehren Minuten auf einige Sekunden!

Vielleicht siehst Du dann einen Flaschenhals ...

Grüße
Rolf

Jasocul 26. Jul 2016 07:17

AW: Array in SQL
 
Hi roldi,

es werden alle Datensätze aller genutzten Tabellen sequentiell durchlaufen und für den Test habe ich alles deaktiviert, was die Daten verändert. Ein fehlender Index ist ganz sicher nicht das Problem.

Ich habe aber jetzt zur Sicherheit noch einen Test-Durchlauf gemacht.
- Durchlauf der kann 500.000 Datensätze ohne einen Änderungs-Cursor dauert ca. 15 Sekunden
- Mit Aktivierung eines Änderungs-Cursor (ohne irgendwelche weiteren Aktionen) knapp 3 Minuten

rokli 26. Jul 2016 07:31

AW: Array in SQL
 
Du durchläufst 500' Sätze und gehst bei jedem Satz die kleinen (Cursor-) Tabellen durch?

Kannst Du das evtl. anders miteinander verbinden?

Jasocul 26. Jul 2016 07:40

AW: Array in SQL
 
Leider nicht.
Ich muss in 2-3 Feldern ein Wort-Splitting machen, dabei verschiedene Neben-Bedingungen beachten, bestimmte Wörter ignorieren/ersetzen. Teilweise betrifft das auch nur einzelne Buchstaben. Joins oder ähnliches sind auf diese Weise nicht zu realisieren, da die Inhalte durch die Operationen ja variabel sind.

Gebraucht wird das für:
Pro Datensatz wird dann je zulässigem Wort in eine neue Tabelle geschrieben/aktualisiert. Diese dient dann der Überprüfung, ob neue, ähnliche oder gleiche Daten bei der nächsten Daten-Lieferung kommen.

rokli 26. Jul 2016 07:47

AW: Array in SQL
 
puh :cry:

Aviator 26. Jul 2016 09:15

AW: Array in SQL
 
Zitat:

Zitat von Jasocul (Beitrag 1343384)
Leider nicht.
Ich muss in 2-3 Feldern ein Wort-Splitting machen, dabei verschiedene Neben-Bedingungen beachten, bestimmte Wörter ignorieren/ersetzen. Teilweise betrifft das auch nur einzelne Buchstaben. Joins oder ähnliches sind auf diese Weise nicht zu realisieren, da die Inhalte durch die Operationen ja variabel sind.

Gebraucht wird das für:
Pro Datensatz wird dann je zulässigem Wort in eine neue Tabelle geschrieben/aktualisiert. Diese dient dann der Überprüfung, ob neue, ähnliche oder gleiche Daten bei der nächsten Daten-Lieferung kommen.

Kann man diese Bearbeitung der Wörter evtl. in dem anderen DBMS machen indem ein OnInsert/OnUpdate Event eingebaut wird? Keine Ahnung ob das an der Geschwindigkeit was ausmacht, aber vielleicht kannst du es ja mal probieren.

TRomano 26. Jul 2016 09:26

AW: Array in SQL
 
Wenn ich das richtig verstanden habe läuft diese Stored Procedure einmal täglich mit einer Dauer von 15 sec. ? Lohnt sich da wirklich der Aufwand stundenlang zu Forschen, zu Proggen und zu Testen ? Oder ist das eine Fingerübung ?
Hat der DB-Server deine volle Aufmerksamkeit (keine anderen Jobs), sind die Parameter der DB so eingestellt, dass er bei bestimmten Operationen (z.B. ORDER BY) keinen Speichermangel hat und kann man vielleicht die Verarbeitung der Daten auf dem Client machen, um den Server zu entlasten. Alles Fragen, die gestellt werden sollten ...

Jasocul 26. Jul 2016 09:47

AW: Array in SQL
 
Hallo Aviator,
das wäre nur eine sehr theoretische Möglichkeit, da ich selbst keinen Zugriff auf die anderen DB-Systeme habe.
So muss ich mit dem leben, was ich bekomme.
Zitat:

Zitat von Aviator (Beitrag 1343406)
OnInsert/OnUpdate Event eingebaut wird? Keine Ahnung ob das an der Geschwindigkeit was ausmacht, aber vielleicht kannst du es ja mal probieren.

Delphi ist da komplett außen vor. So ein Event gibt es also nicht. Die Überlegung das über Datenbank-Trigger zu machen, habe ich praktisch sofort verworfen, da die Daten im ersten Schritt über ein Bulk-Insert eingelesen werden. Die Trigger sind da meines Wissens nicht aktiv. Selbst wenn doch, würde dann der Cursor für die kleinen Tabellen jedesmal pro Datensatz neu erstellt werden, was die Performance noch weiter verschlechtert würde.

@TRomano:
Die 15 Sekunden erreiche ich nur, wenn ich die beiden Cursor zum Abgleich nicht verwende. Sobald die aktiviert werden, dauert es ca. 10 Minuten.
Wenn ich es vom Server auslagere, habe ich ja auch noch eine Schicht mehr.
Der Server hat zu dem Zeitpunkt nichts anderes zu tun, außer weitere Jobs durchzuführen, die aber sowieso sequentiell abgearbeitet werden müssen. Allerdings ist das auch der Grund, warum die Performance besser werden sollte.
Speicher ist genug da.
Im Moment habe ich einen Test-Server, der sehr ähnlich ausgestattet ist, aber wirklich sonst nichts zu tun hat.

Aviator 26. Jul 2016 10:48

AW: Array in SQL
 
Zitat:

Zitat von Jasocul (Beitrag 1343416)
Delphi ist da komplett außen vor.

Das hatte ich mir gedacht. War nur dummerweise nicht mehr auf die Trigger Bezeichnung gekommen. Deshalb Event. :oops:

MichaelT 26. Jul 2016 11:01

AW: Array in SQL
 
Ich kenne mich am SQL Server nicht aus und auch dein Programm nicht. Somit kann ich nur raten.

Bitte nicht prügeln wenn die Idee Unsinn ist. Rechnest du die Statistiken und machst du Zugriffsoptimierung über Statistiken. So ich mich ganz düster erinnere war da mal was. Welche Ausführungspläne bei welchem Cursor wie gezogen werden und wie man die traced weiß ich ehrlich nichts mehr.

Meine Grundsätzliche Überlegung wäre. 15 Sekunden auf 10 Minuten sind Faktor 40. Das wären so im Mittel 2 Tabellen bei denen die Hälfte der Datensätze durchkämmt wird pro Zugriff. Hat der Cursor zu wenig Einträge oder sind eventuell Statistiken nicht aktuell oder so ähnlich. Scrollable Cursor ist gut für viele Rows, wenn man nachschlagen muss.

Kennst du die Anzahl der Zeilen in den Nachschlagetabellen und hilft es wenn man diese fixiert ala static. Das Nachschlagen geht auf die tempdb & KEYSET (musste kurz nachschauen) oder STATIC.

Die Frage die sich mir stellt, ob sich die gewonnene Flexibilität durch SCROLL tatsächlich im Mittel auszahlt und ob man nicht auf ReadOnly und ForwardOnly nimmt. Ob diese Variante schneller ist kann ich so nicht beurteilen. Zumal diese Cursor keine echten in memory buffer sind scheint mir die variante einen Stand aus der tempdb zu lesen noch eher die 'beste' Annährung oder eben ein KEYSET usw..

Stellt sich die Frage ob du die tempdb nicht auf ein RAMDRIVE kannst legen. Aber das ist schon etwas gewagt. Die tempdb wird an sich von alle benutzt. Wäre allein interessant zu sehen, ob es einen Unterschied macht zur tempdb auf Platte. Vermute die Datenbankseiten sollten sowieso gepuffert sein.


Jasocul 26. Jul 2016 11:32

AW: Array in SQL
 
@Aviator:
Kein Problem. Manchmal sind es die einfachen Dinge, die zur Lösung führen, weil man zu kompliziert denkt.

@MichaelT:
Alle Daten werden sequentiell verarbeitet (alles ohne order by, joins, ...). Die Aktualisierungen natürlich nicht, aber die sind im Test auch nicht aktiviert. Die Statistiken können somit keine Rolle spielen.

Aber der Hinweis auf Static hat mich ein bisschen weiter gebracht. Allerdings war es read_only, was mir 2 Minuten Verbesserung gebracht hat. Danke für den Anstoß. Static bringt in diesem Zusammenhang nur ein paar Sekunden.

Ich bewege mich also jetzt zwischen 7 und 8 Minuten, was schon deutlich besser ist, aber immer noch relativ lange ist. Weitere Tipps sind willkommen.

Papaschlumpf73 26. Jul 2016 12:11

AW: Array in SQL
 
Bei so wenigen Datensätzen in den Nachschlagetabellen könnte eine Tabellenvariable deutlich schneller sein als eine temporäre Tabelle.

DECLARE @MyTableVar table(ID int, ...)

Jasocul 26. Jul 2016 13:01

AW: Array in SQL
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1343455)
Bei so wenigen Datensätzen in den Nachschlagetabellen könnte eine Tabellenvariable deutlich schneller sein als eine temporäre Tabelle.

Hatte ich das noch nicht geschrieben? Sorry.
Es gibt dabei keinen zeitlichen Unterschied. Ich habe den Eindruck, dass der Server intern eine temporäre Tabelle dafür anlegt. Ich muss ja auch bei einer Tabellen-Variablen einen Cursor verwenden. Oder gibt es dann andere Möglichkeiten, die ich übersehen habe und die schneller ist?

hanvas 26. Jul 2016 13:20

AW: Array in SQL
 
Zitat:

Zitat von Jasocul (Beitrag 1343371)
Hinweis auf Cross-Posting:
Enwickler-Ecke
Hat jemand eine Idee, wie das ganze optimiert werden kann?

Das naheliegendste, aber vermutlich bist Du darauf selbst schon gekommen -> Wenn die Zeichen und Wortersetzungen reproduzierbar bei gleichen Input immer den gleichen Output erzeugen (also nicht Abhängig von Tag, Uhrzeit etc. sind) und die 500 k Datensätze nicht jeden Tag neu erzeugt bzw geändert werden, dann müsste es doch möglich sein den Output einmal für alle Datenstätze vorrauszuberechnen und ggf. in zusätzlichen und von mir aus auch redundanten Feldern oder in einer eigenen Relation zu speichern.

Damit würde sich der Aufwand darauf reduzieren die neu hinzugekommenen oder geänderten Werte zu übersetzen. Je nach Aufwand kann man das durch einen Aufruf deiner SP machen oder direkt bei der Eingabe / Änderung mittels eines Triggers reagieren.

cu Ha-Jö

Jasocul 26. Jul 2016 14:09

AW: Array in SQL
 
Ja, das habe ich natürlich gemacht. :wink:
Aber jeder Hinweis kann helfen. Könnte ja sein, dass ich mich irgendwo verrannt habe.

Die Dauer für die erste Erstellung der Abgleich-Tabellen ist ca. eine halbe Stunde.
Die tägliche Aktualisierung liegt jetzt bei ca. 7 Minuten.

hanvas 26. Jul 2016 14:48

AW: Array in SQL
 
Zitat:

Zitat von Jasocul (Beitrag 1343484)
Ja, das habe ich natürlich gemacht. :wink:
Aber jeder Hinweis kann helfen. Könnte ja sein, dass ich mich irgendwo verrannt habe.

Dann hätte ich noch zwei.

1. In einem anderen Post hast Du geschrieben das es sich um einen Bulk-Insert handelt. Wenn ich richtig vermute liegen die einzufügenden Daten dann in irgendeiner Form extern vor. Wenn es sich bei den einzufügenden Daten (beispielsweise) um Textdateien handelt, dann könntest Du die Umwandlung/Übersetzung doch vor dem Einfügen der Datensätze in bearbeiten. Du könntest Dir ein Programm schreiben das die externen Daten übernimmt, die gewünschten Berechnungen durchführt und dann entweder in die DB schreibt oder ebenfalls wieder extern ablegt.

Wenn keine Abhängigkeiten zwischen den einzelnen Datensätzen existieren dann könntest Du die einzufügenden Daten aufteilen und in mehreren Threads bzw. Prozessen, wenn es sein muss sogar über mehrere Rechner verteilt, verarbeiten und nach der Verarbeitung die Originaldaten wieder zusammenfügen oder häpchenweise bearbeiten.

2. Falls die Datensätze aus mehreren Datenquellen kommen und nicht alle gleichzeitig behandelt werden müssen bzw. zu unterschiedlichen Zeiten zur Verfügung stehen, könnte es Sinn machen jede Datenquelle einzeln zu behandeln und das Ergebnis temporär abzuspeichern, und später alles zusammen, also wenn alle Daten vorhanden und umgewandelt sind, zu kopieren. Die Erzeugung der Zwischenergebnisse kann man im Hintergrund laufen lassen so das am Ende nur die Einfügeoperation der bearbeiteten Daten Last erzeugt.

3. (Abwandlung und Kombination von 1 und 2) Falls es mehrere Datenlieferanten auf mehreren Rechnern gibt und meine Annahme mit den externen Dateien richtig ist, wäre es auch eine Möglichkeit das jeder Datenlieferant bzw. jede Maschine vor dem Export der Daten diese selbst aufarbeitet und die aufgearbeiteten Daten an den DB Server liefert.

cu Ha-Jö

MichaelT 26. Jul 2016 15:58

AW: Array in SQL
 
Gerne. Ich habe das nur geschwind aus der Doku nachgeschlagen.

READ ONLY glaube ich sofort. 2 Minuten war nicht der Big Win :-D

Gut. Soweit ich die CURSOR Thematik am SQL Server have verstanden.

Ich gehe jetzt mal davon aus, dass du den CURSOR nicht so einfach kannst ersetzen...

Damit verbleiben jetzt mal 2 Varianten
a) Sortieren
a1) In der Hoffnung, dass der SQL Server einen Index nimmt oder so
b) Sequentiell durchklappern und die wahrscheinlicheren Kombinationen vorne anstellen.
b1) Möglw. hilft das vermeiden von der Neuerstellung von Execution Plans beim Absetzen von Queries

Möglw. kannst du einen Clustered Index verwenden, je nachdem kann das etwas bringen.

Wenn das nichts hilft dann temporary table mit Schlüssel. Die Frage bleibt ob du überhaupt einen Schlüssel hast usw..

Mir kommt aber vor, dass aus irgendeinem Grund bei der Navigation jedes mal ein Statement wird abgesetzt.

Selbst im ABAP bei einer unsortierten Tabelle (in memory buffer ohne key) verliert man zwar Zeit aber bei weitem nicht in der Dimension. Das einzige mal bei dem mir Laufzeitunterschiede in der Dimension unterkam (mal von SQL abgesehen) war als der ABAP Prozesser aufgrund von Cluster


Gruß


Zitat:

Zitat von Jasocul (Beitrag 1343445)
@Aviator:
Kein Problem. Manchmal sind es die einfachen Dinge, die zur Lösung führen, weil man zu kompliziert denkt.

@MichaelT:
Alle Daten werden sequentiell verarbeitet (alles ohne order by, joins, ...). Die Aktualisierungen natürlich nicht, aber die sind im Test auch nicht aktiviert. Die Statistiken können somit keine Rolle spielen.

Aber der Hinweis auf Static hat mich ein bisschen weiter gebracht. Allerdings war es read_only, was mir 2 Minuten Verbesserung gebracht hat. Danke für den Anstoß. Static bringt in diesem Zusammenhang nur ein paar Sekunden.

Ich bewege mich also jetzt zwischen 7 und 8 Minuten, was schon deutlich besser ist, aber immer noch relativ lange ist. Weitere Tipps sind willkommen.


jobo 26. Jul 2016 18:09

AW: Array in SQL
 
Ich habe nicht alle Antworten gescannt. Würde sowas helfen?
SQL-Code:
DECLARE @ListOfWord TABLE(aWord VARCHAR(100), aCategoryID VARCHAR(100), aID IDENTITY(1,1)); -- oder so ähnlich
INSERT INTO @ListOfWord
SELECT tword, tcat from WordTable;

SELECT * FROM @ListOfWord;
GO
Hab kein MSSQL im Einsatz, also ist es nur Theorie. Macht nur Sinn, wenn die Werte auf diesem Weg gecached werden, statt immer erneut aus der Originaltabelle gelesen zu werden.

Ansonsten wäre es auch nicht verkehrt, das Statement selbst mal hier zu zeigen oder die Hilfsoperationen.

Jasocul 27. Jul 2016 06:07

AW: Array in SQL
 
@jobo:
Im Prinzip mache ich es bereits genau so. Das hat aber keinen erkennbaren Unterschied gemacht.

@hanvas:
Wirkt ein wenig, wie mit Kanonen auf Spatzen, wobei es prinzipiell besser sein würde, näher an der Quelle der Daten zu arbeiten.

Ich hatte gestern beim Einschlafen noch eine Idee, die ich heute ausprobieren werde.
Ansatz: Ich bastel mir einen String, der einen definiertes Trennzeichen zwischen den Datensätzen und einen anderen zwischen den Wortpaaren hat. Alternativ nehme ich zwei Strings. Über Charindex durchlaufe ich dann die Listen anstatt den Cursor zu durchlaufen. Bin gespannt, wie effektiv das ist.

EDIT ERGEBNIS:
Die dadurch notwendigen String-Operationen kosten soviel Performance, dass es kaum einen Vorteil bringt.

Jasocul 27. Jul 2016 10:25

AW: Array in SQL
 
Nach eingehender Untersuchung meiner String-Operationen, konnte ich noch doch noch einiges rauskitzeln.
Von der ursprünglichen Laufzeit von ca. 10 Minuten, bin ich jetzt runter auf unter 6,5 Minuten und ich habe noch einige Stellen gesehen, die potential haben.

Der Trick:
Es geht ja um Wort- und Buchstaben-Ersetzung mit verschiedenen Nebenbedingungen. Die Bedingungen lasse ich aber jetzt mal weg. Die Austauschtabellen haben insgesamt keine 100 Datensätze, sind also ziemlich kein.

Ich habe mir zwei varchar-Variablen und zwei Integer-Variablen deklariert.
Über einen Cursor fülle ich varchars mit einem Trennzeichen zwischen den Feldern. Einer enthält die Suchbegriffe und der andere die Ersetzungsbegriffe.
Die Integer halten in einer Schleife fest, bei welchem "Index" ich mich befinde. Bestimmt wird das über den Charindex des Trennzeichens.

Ich bin mit der Lösung erstmal zufrieden. Jetzt muss ich nur noch schauen, wo ich die String-Operationen optimieren kann.

Sir Rufo 27. Jul 2016 11:06

AW: Array in SQL
 
Zeig doch mal die Definition von dem Cursor.

Es gibt da die ein oder andere Möglichkeit so einen Cursor schneller zu machen.
https://msdn.microsoft.com/de-de/library/ms180169.aspx

Jasocul 27. Jul 2016 11:30

AW: Array in SQL
 
Code:
declare crsParam1 cursor scroll READ_ONLY for
select Begriff, Ersatz from @ParamTable1
scroll ist leider zwingend.
Ich habe auch mit local und static getestet. Die haben aber keinen spürbaren Effekt.

Sir Rufo 27. Jul 2016 11:40

AW: Array in SQL
 
Nur so als Versuch
SQL-Code:
declare crsParam1 cursor
LOCAL scroll STATIC READ_ONLY for
select Begriff, Ersatz from @ParamTable1
Ok, hast du ja schon gemacht ...

jaevencooler 27. Jul 2016 13:23

AW: Array in SQL
 
Hi Jasocul,

oder benutze endlich eine Oracle, die kann das :-D

Beste Grüße
Michael

Jasocul 27. Jul 2016 13:30

AW: Array in SQL
 
Hi Michael,

Ich leide schon genug. :roll: :wink:

jobo 27. Jul 2016 13:47

AW: Array in SQL
 
Zitat:

Zitat von Jasocul (Beitrag 1343582)
Ich leide schon genug. :roll: :wink:

Das siehst Du total falsch, kann man prima mit arbeiten.

Zum Thema
Letztlich kostet es halt etwas mehr Zeit 500T x100 Ops zu verarbeiten, als eben nur 500T. Dabei geht es dann vielleicht einfach nur um flinke Suchen&Ersetzen Algos. Ob TSQL sich da mit den Cursorn sturer anstellt als notwendig, kannst Du allerdings nur selbst rausfinden, wenn Du nicht mehr Infos lieferst.

P.S.: Gerade noch mal "Index " gelesen.
Wenn entsprechend häufige Änderungen wirklich erfolgen, ist der Zeitvergleich auch gerade wegen des Index unfair, weil der auch 500Tx100 worstcase geändert wird.
Für den Cursor und die Rohgeschwindigkeit ist er vermutlich eh irrelevant, hast Du schon mal probiert, wie es mit gelöschten Indizex läuft?
Kann SQL Server die Indexaktualisierung verzögern bzw. aussetzen?

MichaelT 27. Jul 2016 14:07

AW: Array in SQL
 
Hast du einen Index auf der 'großen' Tabelle der laufend upgedated wird?

Ok, jobo war flinker.

Wobei sich sofort die Frage stellt. Wieviele Datensätze Altbestand werden angegriffen bei der Verarbeitung usw...

Dann mal einen Test mit der doppelten bis 4 fachen Datenmenge machen.



Jasocul 27. Jul 2016 15:04

AW: Array in SQL
 
Jedes DBMS hat Vor- und Nachteile. Ich komme halt ursprünglich aus der Oracle-Ecke.

Die Zieltabelle hat zwar einen Index, aber das ist kein Problem. Ohne Index würde ich vermutlich Stunden warten. Die Zieltabelle hat etwa 1,3 Mio Datensätze und ist definitiv nicht der Flaschenhals. Das weiß ich deswegen, weil ich alle Aktionen auf dieser Tabelle für die Tests deaktiviert habe.

Auf die Tabelle, die mir die zu prüfenden Datensätze liefert greife ich sequentiell zu. Die Reihenfolge spielt keine Rolle und es ist nur ein lesender Zugriff.

Die Tabelle für den Abgleich lese ich ja inzwischen nur noch einmal ein, damit ich mein neues Verfahren (nenne ich es mal Pseudo-Array-Verfahren) nutzen kann.

Dieses Verfahren hat ja schon etwas gebracht, allerdings bremst mich die Funktion Charindex jetzt erheblich aus, die ich dann doch ein paar mal mehr benötige, als erwartet.

Hier mal der Ausschnitt, der mich ausbremst (ist SQL-Code, kein Delphi-Code):
Delphi-Quellcode:
while @@FETCH_STATUS = 0
  begin
    -- Aufbereitung des Namens für die weitere Verarbeitung
    set @Str = @Name1
    set @Str = ' ' + lower(@Str) + ' ' -- Alles in Kleinbuchstaben
    set @Ort = lower(@Ort)

    set @WortPos1 = 0
    set @WortPos2 = 0

-- Abgleichliste durchlaufen
    while @WortPos1 < LEN(@WortList1)
    begin
      set @Pos = CHARINDEX(@Delimiter, @WortList1, @WortPos1 + 1)
      set @Wort1 = Substring(@WortList1, @WortPos1 + 1, @Pos - @WortPos1 - 1)

      if CHARINDEX(@Wort1, @Str) > 0
      begin
        set @Pos = CHARINDEX(@Delimiter, @WortList2, @WortPos2 + 1)
        set @Wort2 = Substring(@WortList2, @WortPos2 + 1, @Pos - @WortPos2 - 1)
      end
      if Len(@Wort1) = 1
      begin
        if CHARINDEX(@Wort1, @Ort) > 0
        begin
          set @Pos = CHARINDEX(@Delimiter, @WortList2, @WortPos2 + 1)
          set @Wort2 = Substring(@WortList2, @WortPos2 + 1, @Pos - @WortPos2 - 1)
          set @Ort = replace(@Ort, @Wort1, @Wort2)
        end
      end

      set @WortPos1 = charindex(@Delimiter, @WortList1, @WortPos1+1)
      set @WortPos2 = charindex(@Delimiter, @WortList2, @WortPos2+1)
    end
    fetch next from crsDeb into @Name1, @Ort
  end
Das ist nur C&P und ein bisschen bereinigt. Ich hoffe, es ist lesbar.
Wie man sieht, benötige ich oft charindex. Pro 10.000 Datensätze des Haupt-Cursors, verursacht charindex eine Sekunde Zeit. Ich habe auch schon probiert, es durch ein "Like" zu ersetzen (wo es theoretisch ginge), aber ohne Effekt.

Vielleicht kann man auch einfach nicht mehr rausholen. :gruebel:

Meine Birne raucht, ich mache jetzt erst mal Feierabend.

Jasocul 28. Jul 2016 07:37

AW: Array in SQL
 
Sooo, eine Nacht drüber geschlafen und Thema erledigt.
Man kann sicher noch ein paar Sekunden rauskitzeln, aber bei den Datenmengen und den notwendigen Vergleichen, gibt es einfach Grenzen.

Also habe ich einen neuen Ansatz gemacht, und die zu prüfende Datenmenge reduziert. Statt der halben Mio Datensätze, sind es dadurch zur Zeit nur noch wenige hundert. Selbst wenn es ein paar tausend werden, dauert der Abgleich nur noch ein paar Sekunden.

Trotzdem Danke an alle, die sich mit mir den Kopf zerbrochen haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz