AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Array in SQL

Ein Thema von Jasocul · begonnen am 26. Jul 2016 · letzter Beitrag vom 28. Jul 2016
Antwort Antwort
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
558 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Array in SQL

  Alt 26. Jul 2016, 15:58
Gerne. Ich habe das nur geschwind aus der Doku nachgeschlagen.

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

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ß


@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.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#2

AW: Array in SQL

  Alt 26. Jul 2016, 18:09
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.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.371 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Array in SQL

  Alt 27. Jul 2016, 06:07
@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.
Peter

Geändert von Jasocul (27. Jul 2016 um 08:33 Uhr) Grund: Ergebnis ergänzt
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.371 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Array in SQL

  Alt 27. Jul 2016, 10:25
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.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Array in SQL

  Alt 27. Jul 2016, 11:06
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
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (27. Jul 2016 um 11:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.371 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Array in SQL

  Alt 27. Jul 2016, 11:30
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.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Array in SQL

  Alt 27. Jul 2016, 11:40
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 ...
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
558 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Array in SQL

  Alt 27. Jul 2016, 14:07
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.


  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.371 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Array in SQL

  Alt 27. Jul 2016, 15:04
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.

Meine Birne raucht, ich mache jetzt erst mal Feierabend.
Peter

Geändert von Jasocul (27. Jul 2016 um 15:10 Uhr) Grund: CODE-Tags funktionieren nicht
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.371 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Array in SQL

  Alt 28. Jul 2016, 07:37
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.
Peter
  Mit Zitat antworten Zitat
Antwort Antwort

 
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 +1. Es ist jetzt 23:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz