Re: =?UTF-8?Q?Re: SQL-DB Lesen =c3=bcber ODBC-Treiber
Von:Harro Schippan hs@dtsd.de
An:All :gelesen
erstellt am:08.02.2018 16:48:02 - #23678 in section Antworten     Antworten mit Zitat
Hallo zusammen,
ich lese über einen ODBC-Treiber in einer GUPTA-Datenbank.
Technisch funktioniert es.
Aber furchtbar lange Antwortzeiten ( mehr als 25 Sekunden )

Das dauert über 25 Sekunden, IMMER
*****************************************************************************
* SQL-Befehl
wSuchOrt = LOWER('Köln')+"%"
SET TEXTMERGE ON
TEXT TO mySQL NOSHOW
SELECT KundenNr, Name1, Strasse, Ort, aNum, datgepl
FROM stellplatz
WHERE
(KundenNr = 100311) AND
(@LOWER(ort) like ?wSuchOrt) AND
(@YEAR(datGepl) = 2015)
ENDTEXT
retcd = SQLEXEC(gnConnHandleKnG ,mySQL , wCurKnG)
*****************************************************************************

Durch Zufall habe ich folgendes probiert
Also diesmal beim Suchen nach Ort nicht ?wSuchOrt sondern <<wSuchOrt>>,
Das dauert 0,14 Sekunden, auch IMMER.
*****************************************************************************
* SQL-Befehl
wSuchOrt = LOWER('Köln')+"%"
SET TEXTMERGE ON
TEXT TO mySQL NOSHOW
SELECT KundenNr, Name1, Strasse, Ort, aNum, datgepl
FROM stellplatz
WHERE
(KundenNr = 100311) AND
(@LOWER(ort) like '<<wSuchOrt>>') AND
(@YEAR(datGepl) = 2015)
ENDTEXT
retcd = SQLEXEC(gnConnHandleKnG ,mySQL , wCurKnG)
*****************************************************************************

Hat jemand eine Idee was diese ResponseZeitUnterschiede bewirkt?????
Ich bin total verblüfft.

Habe ein paar Batch-Programm, alle samt Langläufer.
Das wäre ja eine Revolution bei der Laufzeit.

Danke und Gruß
Harro

Von:Thomas Geissler softart@t-online.de
An:Harro Schippan hs@dtsd.de :gelesen
erstellt am:08.02.2018 17:48:42 - #23679 in section Antworten     Antworten mit Zitat
Hallo Harro,

ich würde dieses Verhalten eher als normal abtun nur hätte ich nicht diesen Geschwindigkeitsunterschied erwartet.

In der ersten Variante wird wohl jeder Datensatz erst noch mit dem Inhalt der Variable geprüft, während bei der zweiten Variante der zu vergleichende Wert schon feststeht.

Gruß
Thomas

Von:Harro Schippan hs@dtsd.de
An:Thomas Geissler softart@t-online.de :gelesen
erstellt am:09.02.2018 09:32:03 - #23680 in section Antworten     Antworten mit Zitat
 

nur hätte ich nicht diesen Geschwindigkeitsunterschied erwartet.



Hallo Thomas,
genau der Geschwindigkeitsunterschied hat mich verwundert.

Bin mittlerweile einen Schritt weiter.
Es ist so, daß bei "?SuchBegriff" in Verbindung allen Logik-Operatoren außer bei "=" (GLEICH) der GUPTA-Server keine Indices benutzt.

Warum das so ist, weiß ich allerdings (noch) nicht.

Bekomme jetzt noch ein GUPTA-SQL-Performance-Programm.
Das protokolliert alles was auf der GUPTA-Seite während einer QUERY passiert.

Ich dachte bisher diese ?-Substitution sei "State of the Art".

Hatte bisher damit auch noch kein Problem.
Allerdings waren bisher meine Tabellen auch nicht in der Größe.
Hier habe ich es mit einer großen Tabelle (viele Felder) mit mehr als 800.000 Datensätzen zu tun.

Falls noch jemand was dazu beitragen kann, würde ich mich freuen.

Gruß Harro

Von:Tom Knauf knauf@pdtgmbh.de
An:Harro Schippan hs@dtsd.de :gelesen
erstellt am:09.02.2018 09:36:36 - #23681 in section Antworten     Antworten mit Zitat
--from Newsreader at Freitag, 9. Februar 2018; 09:36:36--

Hallo Harro,

was passiert wenn du die Abfrage umdrehst, also erst den Teil mit dem Year ?

Gruesse
tom

Seltsam, beim MS-SQLserver soll man mit Variablen arbeiten...



"Harro Schippan" schrieb im Newsbeitrag news:741061...

--------------------------------------------------------------------------

nur hätte ich nicht diesen Geschwindigkeitsunterschied erwartet.

--------------------------------------------------------------------------



Hallo Thomas,
genau der Geschwindigkeitsunterschied hat mich verwundert.

Bin mittlerweile einen Schritt weiter.
Es ist so, daß bei "?SuchBegriff" in Verbindung allen Logik-Operatoren außer bei "=" (GLEICH) der GUPTA-Server keine Indices benutzt.

Warum das so ist, weiß ich allerdings (noch) nicht.

Bekomme jetzt noch ein GUPTA-SQL-Performance-Programm.
Das protokolliert alles was auf der GUPTA-Seite während einer QUERY passiert.

Ich dachte bisher diese ?-Substitution sei "State of the Art".

Hatte bisher damit auch noch kein Problem.
Allerdings waren bisher meine Tabellen auch nicht in der Größe.
Hier habe ich es mit einer großen Tabelle (viele Felder) mit mehr als 800.000 Datensätzen zu tun.

Falls noch jemand was dazu beitragen kann, würde ich mich freuen.

Gruß Harro


Von:Matthias Kahlert usenet@max-pro.de
An:Tom Knauf knauf@pdtgmbh.de
erstellt am:14.02.2018 23:13:55 - #23685 in section Antworten     Antworten mit Zitat
--from Newsreader at Mittwoch, 14. Februar 2018; 23:13:55--

Am 09.02.2018 um 09:36 schrieb Tom Knauf:
> Seltsam, beim MS-SQLserver soll man mit Variablen arbeiten...

Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten,
denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren.
Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann
er den bereits vorkompilierten SQL-Befehl wiederverwenden.

Wenn die Variable bereits als String im SQL-Befehl drinsteht, dann ist
jeder SQL-Befehl für den SQL-Server neu, er muss neu kompilieren, neue
Statistiken generieren, etc.

--
Matthias
Von:Harro Schippan hs@dtsd.de
An:Matthias Kahlert usenet@max-pro.de
erstellt am:15.02.2018 07:41:49 - #23686 in section Antworten     Antworten mit Zitat
Habe gestern noch mal mit einem GUPTA-Spezialisten an dem Thema gesessen.
Dabei haben wir festgestellt, daß der GUPTA-Server bei Benutzung der BindVariablen (?wSuchOrt) nicht mir dem richtigen INDEX arbeitet.
Daher kommen die langen AntwortZeiten.

Interessant ist, daß bei der Substitution ( <<wSuchOrt>> ) - anstelle der BindVariablen - der richtige INDEX benutzt wird.

Der Spezi klärt nun die Ursache mit dem Hersteller.

Ich komme erst mal weiter.

Aber man muß tatsächlich bei Queries erst mal prüfen, ob die richtigen Indices benutzt werden. Zumindest bei GUPTA,

Möglicherweise ist das auch ein reines GUPTA-Problem.

Gruß Harro

Gibt beim MS-SQL-Server eigentlich auch ein Tool mit dem man prüfen kann wie eine Query abgearbeitet wird?
War bisher noch nicht auf die Idee gekommen.

Von:Jens Brand foxnews.9.jbrand@spamgourmet.com
An:Harro Schippan hs@dtsd.de :gelesen
erstellt am:15.02.2018 09:00:15 - #23687 in section Antworten     Antworten mit Zitat
--from Newsreader at Donnerstag, 15. Februar 2018; 09:00:15--

Hallo Harro,

>
> Gibt beim MS-SQL-Server eigentlich auch ein Tool mit dem man prüfen kann
> wie eine Query abgearbeitet wird?
> War bisher noch nicht auf die Idee gekommen.

Im Microsoft SQL Server Management Studio gibt es in der Symbolleiste
eine Schaltfläche mit dem ToolTip "Tatsächlichen Ausführungsplan
einschließen". Wenn du diesen Schalter einschaltest und dann eine
Abfrage ausführst, dann bekommst du eine graphische Darstellung, wie die
Ausführung ausgesehen hat, sehr informativ.



Viele Grüße

Jens Brand
Von:Harro Schippan hs@dtsd.de
An:Jens Brand foxnews.9.jbrand@spamgourmet.com
erstellt am:15.02.2018 11:22:44 - #23688 in section Antworten     Antworten mit Zitat
Hallo Jens,
danke, werde ich ausprobieren.
Gruß Harro

Von:Hans-Peter Grözinger hanspetergr@gmx.de
An:Matthias Kahlert usenet@max-pro.de
erstellt am:15.02.2018 12:35:08 - #23689 in section Antworten     Antworten mit Zitat
Hallo Matthias !

 
beim MS-SQLserver soll man mit Variablen arbeiten...
Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten,
denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren.
Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann
er den bereits vorkompilierten SQL-Befehl wiederverwenden.

Hast du da einen Link wo das gut beschrieben ist?


--
Hans-Peter
Von:Tom Knauf knauf@pdtgmbh.de
An:Hans-Peter Grözinger hanspetergr@gmx.de :gelesen
erstellt am:15.02.2018 18:02:18 - #23691 in section Antworten     Antworten mit Zitat
--from Newsreader at Donnerstag, 15. Februar 2018; 18:02:18--

http://db-berater.blogspot.de/2014/07/verwendung-von-variablen-statt-literalen.html


"Hans-Peter Grözinger" schrieb im Newsbeitrag news:741070...
Hallo Matthias !


--------------------------------------------------------------------------
beim MS-SQLserver soll man mit Variablen arbeiten...
Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten,
denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren.
Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann
er den bereits vorkompilierten SQL-Befehl wiederverwenden.
--------------------------------------------------------------------------

Hast du da einen Link wo das gut beschrieben ist20


Von:Hans-Peter Grözinger hanspetergr@gmx.de
An:Tom Knauf knauf@pdtgmbh.de
erstellt am:15.02.2018 19:01:10 - #23692 in section Antworten     Antworten mit Zitat
Hallo Tom !

 
 
Hast du da einen Link wo das gut beschrieben ist
http://db-berater.blogspot.de/2014/07/verwendung-von-variablen-statt-literalen.html


Danke für diesen Link

So ganz habe ich das ganze Szenario noch nicht verstanden

Wie muss denn der SQL-SELECT auf VFP-Seite genau aussehen?
Beispiel:
*-- Kurzzeichen des Benutzers.
lcUser = 'HPG'
lcSQLSelect = 'SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = ?lcUser'

Ich lasse dann ausführen:
lnResult = SQLEXEC( lnConnection, lcSQLSelect, 'cursResult' )

Was passiert denn jetzt bei dem SQLEXEC genau?

Wandelt der ODBC-Treiber oder die VFP-Funktion SQLEXEC den SELECT noch um weil ein ? im SELECT steht in:
DECLARE @KurzZeichen CHAR(3) = N'HPG';
SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = @KurzZeichen';

Es wäre hilfreich mir hier noch etwas aufs Pferd zu helfen, im Steigbügel stehe ich schon mal


--
Hans-Peter
Von:Harro Schippan hs@dtsd.de
An:Hans-Peter Grözinger hanspetergr@gmx.de :gelesen
erstellt am:16.02.2018 08:54:21 - #23693 in section Antworten     Antworten mit Zitat
Hi,
dieser Artikel bringt da auch noch mal etwas Hintergrund:
http://www.db-berater.de/2016/12/abfragen-nicht-mit-variablen-testen/

Was mich jetzt noch irritiert: es hat doch immer geheißen man solle Bind-Variable in Queries verwenden.

Ich lese diese Artikel jetzt aber so, daß man mit Literalen die schnellere Lösung hat.

Das haben auch meine Test ergeben.
Wobei die gravierenden Zeitunterschiede nur bei meiner großen Tabelle ( mehr als 800.000 Datensätze ) zum Tragen kommen.
Der GUPTA-Server verwendet bei der Bind-Variablen keinen INDEX.
Beim Literal wird der Index verwendet.
Neueste Messung mit verschiedenen Werten:
Mit Bind-Variable mehr als 22 Sekunden
Mit Literal 0,016 Sekunden

Ich habe die zeitkritischen Statements mit TEXTMERGE <<Suchbegriff>> auf Literale umgestellt. Die Benutzer sind begeistert.

Gruß Harro



Von:Tom Knauf knauf@pdtgmbh.de
An:Tom Knauf knauf@pdtgmbh.de
erstellt am:16.02.2018 16:11:39 - #23694 in section Antworten     Antworten mit Zitat
--from Newsreader at Freitag, 16. Februar 2018; 16:11:39--

Moin, moin

wie Matthias schon beschrieben hat : bei Verwendung von Variablen a la â=80=9C...where kuname = ?m.lckunameâ=80=9D
kompiliert der Server die Abfrage und â=80=9Cmerktâ=80=9D sich Statistiken, etc.
Bei Verwendung von Literalen macht er das nicht, waere ja auch nicht sinnvoll.
Bei Literalen gewinnt der Server Zeit fuer die Abschaetzung (Festwert), verliert aber bei der Statistik und Kompilierung wieder welche.
Testen kann man das nicht per Aufruf von Prozeduren, da gelten, vor allem bei lokalen Variablen, wieder andere Werte.

Wir mischen das eher locker :
Bei hauefig verwendeten Abfragen (FK zu Klartext) nehmen wir Variablen
Bei selteneren , vor allem mit vielen Joins, bauen wir den Wert via Textmerge (nur f=C3=BCr numeric pks). Das liegt auch daran dass die SQL-Funktionen zum Update,.. in Funktionen gekapselt sind und diese dann die lokalen Werte der aufrufenden Funktion nicht kennen.

cKurz = adrkurz(thisform.oadr.pk_adr)
Func adrkurz(nfk)
nnfkadr = nfk && private zwischenvariable, nfk ist in sqlwert() nicht bekannt
return sqlwert(â=80=9CSelect kurzname from adr where pk_adr = ?m.nnfkadrâ=80=9D,â=80=9Dkurznameâ=80=9D, â=80=9CCUAâ=80=9D)
* return sqlwert(â=80=9CSelect kurzname from adr where pk_adr = â=80=9C+Trans(m.nfk),â=80=9Dkurznameâ=80=9D, â=80=9CCUAâ=80=9D) && oder Textmerge
endfu

Bei Uebergabe als Parameter an ODBC ist eine sqlinjection soweit ich weiss nicht moeglich, bei Literalen schon.
https://xkcd.com/327/
https://www.explainxkcd.com/wiki/index.php/Little_Bobby_Tables
https://www.easysoft.com/developer/sql-injection.html


Wir â=80=9Csanitizenâ=80=9D Felder die zur Suche verwendet werden k=C3=B6nnten (kein â=80=93, ; , kein drop , dele,... im Inhalt) nur zur Sicherheit. Die werden aber eh per variable abgefragt


GUPTA scheint da noch anders zu agieren.

Gruesse
tkn

P.S.:

"Tom Knauf" schrieb im Newsbeitrag news:741072...
--from Newsreader at Donnerstag, 15. Februar 2018; 18:02:18--

http://db-berater.blogspot.de/2014/07/verwendung-von-variablen-statt-literalen.html


"Hans-Peter Gr=C3=B6zinger" schrieb im Newsbeitrag news:741070...
Hallo Matthias !


--------------------------------------------------------------------------
beim MS-SQLserver soll man mit Variablen arbeiten...
Richtig, beim SQL Server soll man immer mit den ?-Variablen arbeiten,
denn dann muss der SQL Server den SQL-Befehl nur einmalig kompilieren.
Wird der gleiche SQL-Befehl (mit anderem Wert) erneut aufgerufen, kann
er den bereits vorkompilierten SQL-Befehl wiederverwenden.
--------------------------------------------------------------------------

Hast du da einen Link wo das gut beschrieben ist20



Von:Matthias Kahlert usenet@max-pro.de
An:Hans-Peter Grözinger hanspetergr@gmx.de :gelesen
erstellt am:21.02.2018 02:05:03 - #23695 in section Antworten     Antworten mit Zitat
--from Newsreader at Mittwoch, 21. Februar 2018; 02:05:03--

Am 15.02.2018 um 19:01 schrieb Hans-Peter Gr�zinger:
> So ganz habe ich das ganze Szenario noch nicht verstanden
>
> Wie muss denn der SQL-SELECT auf VFP-Seite genau aussehen?
> Beispiel:
> *-- Kurzzeichen des Benutzers.
> lcUser = 'HPG'
> lcSQLSelect = 'SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen =
> ?lcUser'
>
> Ich lasse dann ausführen:
> lnResult = SQLEXEC( lnConnection, lcSQLSelect, 'cursResult' )
>
> Was passiert denn jetzt bei dem SQLEXEC genau?
>
> Wandelt der ODBC-Treiber oder die VFP-Funktion SQLEXEC den SELECT noch
> um weil ein ? im SELECT steht in:
> DECLARE @KurzZeichen CHAR(3) = N'HPG';
> SELECT VorName, Name FROM tabBenutzer WHERE KurzZeichen = @KurzZeichen';
>
> Es wäre hilfreich mir hier noch etwas aufs Pferd zu helfen, im
> Steigbügel stehe ich schon mal

Wenn du die SQL-Server Vollversion installiert hast, findest Du im SSMS
im Menü Extras --> SQL Server Profiler. Mit dem Profiler kannst Du quasi
die komplette Kommunikation zwischen Server und Client/Applikation
mitlesen. Der siehst Du, welche SQL Befehle durchlaufen, wie viel
CPU-Zeit die jeweils gebraucht haben, wie viele Reads und Writes, und Du
siehst eben auch die echt abgeschickten SQL-Befehl.

Aus Deinem Beispiel wird dann sowas wie:

exec sp_executesql N'SELECT VorName, Name FROM tabBenutzer WHERE
KurzZeichen = @P1 ',N'@P1 varchar(3)','HPG'

Er ruft also in Wahrheit eine StoredProcedure auf, an die der SQL-Befehl
übergeben wird. Der Parameter wird in ein @P1 umgewandelt, und separat
übergeben. Wenn sich also der Parameter ändert, bleibt der SQL-Befehl
identisch.

Im VFP gibt es statt dem SQLEXEC() übrigens auch noch den SQLPREPARE(),
der das SQL-Kommando compiliert ohne es auszuführen, und dann erst
mittels SQLEXEC() ausführt (wobei da der Befehl nicht mehr angegeben
werden muss). Bei Schleifendurchläufen kann man damit also einfach
optimieren.

Zum Beispiel:

SQLPREPARE(lnHandle, "INSERT INTO tabelle ( test ) VALUES ( ?lnI )")
FOR lnI = 1 TO 1000
SQLEXEC(lnHandle)
ENDFOR

Tipp: Mit dem SQL Profiler kann man auch "Fremdprogramme" mitlesen, was
die im SQL Server so machen! Damit kann sogar das SQL Server Management
Studio mitlesen, was der im Hintergrund für SQL Befehle absetzt, wenn
man beispielsweise ein DB-Backup macht oder Optionen verändert.

--
Matthias
Von:Matthias Kahlert usenet@max-pro.de
An:Tom Knauf knauf@pdtgmbh.de
erstellt am:21.02.2018 02:10:29 - #23696 in section Antworten     Antworten mit Zitat
--from Newsreader at Mittwoch, 21. Februar 2018; 02:10:29--

Am 16.02.2018 um 16:11 schrieb Tom Knauf:
> Bei Uebergabe als Parameter an ODBC
> ist eine sqlinjection soweit ich
> weiss nicht moeglich, bei Literalen schon.
> https://xkcd.com/327/
> https://www.explainxkcd.com/wiki/index.php/Little_Bobby_Tables
> https://www.easysoft.com/developer/sql-injection.html

Das ist mit ein Hauptgrund, warum ich zu 99,999% mit Parametern arbeite.
Ich muss mich damit nicht um SQL Injection kümmern, denn die ist dabei
nicht möglich, und ich muss mich auch nicht um Sonderzeichen ö.ä. kümmern.

Oder was machst Du, wenn ein Firmenname eines Kunden >> [Meine] 'tolle'
"Firma" << lautet?

--
Matthias