Delphi-PRAXiS
Seite 3 von 3     123   

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 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 19:12 Uhr.
Seite 3 von 3     123   

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