AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

query.open blockiert

Ein Thema von brechi · begonnen am 7. Nov 2013 · letzter Beitrag vom 12. Nov 2013
Antwort Antwort
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#1

query.open blockiert

  Alt 7. Nov 2013, 09:34
Datenbank: MSSQL • Version: alle • Zugriff über: Zeos/Ado/AnyDac
Hallo,
ich habe verschiedene Komponenten ausprobiert, bei ZEOS/ADO blockiert ein Query.Open bis die kompletten Daten uebermittelt wurden, bei AnyDAC nicht.

Delphi-Quellcode:
  qry.sql.text := 'SELECT * FROM GROSSE_TABELLE';
  qry.open; // <-- erst fertig wenn die Daten uebermittelt wurden bei ZEOS/ADO, schnell bei AnyDAC
  while not qry.eof do begin
    // zeitintensive Berechnung
    qry.next; <-- vermutlich: schnell bei ZEOS/ADO, blockierend bei AnyDAC
  end;
Kann man das Verhalten von AnyDAC irgendwie bei ZEOS/ADO einstellen? Ich moechte die Daten schon verarbeiten, auch wenn diese noch nicht komplett uebertragen wurden (qry.next sollte dann blockieren). Da Uebertragung und Berechnung gleich lange dauern, wuerde es somit quasi parallel ausgefuehrt. Da im Moment das Open bei ZEOS/ADO blockiert dauert alles doppelt so lange...

Ich moechte ungern alles auf Events umstellen (ExecuteOption auf adAsyncExecute) da ich dann selbst den Main/Read-Thread synchonisieren muss.

Edit:
AnyDAC bzw. FireDAC ist mir zu teuer (D2007 Prof Upgrade bei mehreren Nutzern) und diese werden auch nicht mehr supported fuer Delphi2007.
Waere auch mit guenstigen Alternativen zu frieden.

Geändert von brechi ( 7. Nov 2013 um 09:37 Uhr) Grund: Begründung AnyDAC hinzugefuegt
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.195 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: query.open blockiert

  Alt 7. Nov 2013, 10:00
Hallo,
ich habe verschiedene Komponenten ausprobiert, bei ZEOS/ADO blockiert ein Query.Open bis die kompletten Daten uebermittelt wurden, bei AnyDAC nicht.

Kann man das Verhalten von AnyDAC irgendwie bei ZEOS/ADO einstellen? Ich moechte die Daten schon verarbeiten, auch wenn diese noch nicht komplett uebertragen wurden (qry.next sollte dann blockieren).
Kein Problem. Du musst bei ADO die Curserlocation auf clUseServer stellen (Oder ein anderes Property was ich aktuell nicht weiß auf "AsncFetch")
Bei clUseServer belastet man aber den Server erheblicher da er ja die Ergebnismenge noch weiter auf dem Server vorhalten muss.

Da Uebertragung und Berechnung gleich lange dauern, wuerde es somit quasi parallel ausgefuehrt. Da im Moment das Open bei ZEOS/ADO blockiert dauert alles doppelt so lange...
Mit clUseServer könnte es u.U. noch länger dauern. Da wäre dann der Asnchrone Fetch vermutlich besser.

AnyDAC bzw. FireDAC ist mir zu teuer (D2007 Prof Upgrade bei mehreren Nutzern) und diese werden auch nicht mehr supported fuer Delphi2007. Waere auch mit guenstigen Alternativen zu frieden.
Die Devart (http://www.devart.com/de/) kosten zwar einiges, sind aber ihr Geld wert.
Wenn du etwas Zeit und Gehirnschmalz investierst kannst du auch versuchen die dbGo-Wrapper von Delphi zu umgehen und direkt mit der COM-Schnittstelle arbeiten. Bring auch einiges an Performance.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.442 Beiträge
 
Delphi 12 Athens
 
#3

AW: query.open blockiert

  Alt 7. Nov 2013, 10:03
Bei AnyDAC ist standardmäßig ein FetchOnDemand mit einer RowsetSize von 50 aktiv. Damit werden beim Open nur die ersten 50 Datensätze geladen. Inwieweit andere Zugriffskomponenten sowas anbieten und wie, kann ich nicht sagen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#4

AW: query.open blockiert

  Alt 7. Nov 2013, 10:58
Wenn CursorLocation clUseServer ist, dann blockiert "Open" erstmal nicht mehr, aber bei dem x. Query dauert das setzen des SQL-Textes sehr lange:

Delphi-Quellcode:
    Result.SQL.Clear;
    Result.SQL.Add(_SQL);

Intern wird dann:

  ADODB.InternalRefresh
// mit
  RefreshFromOleDB

// aufgerufen, wobei
   if Assigned(CommandPrepare) then CommandPrepare.Prepare(0);

// ewig dauert
Das kann ich also leider nicht verwenden. ExecuteOption AsyncFetch liefert die Daten in einem Extra-Thread, wobei ich mich dann wieder um Synchronisation keumemrn musss, das ist zu viel Aufwand (es werden dann die extra Events aufgerufen).
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#5

AW: query.open blockiert

  Alt 11. Nov 2013, 09:31
Habe mal SDAC (UniDAC) getestet, auch dort blockiert das "Open", selbst wenn FetchAll = False ist.
Weitere Vorschläge (am liebsten fuer ADO)
  Mit Zitat antworten Zitat
EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6
  Alt 11. Nov 2013, 22:51
Hi brechi,

mit ADO selbst werden(soweit mir bekannt) immer alle geladen und konvertiert. Das TADORecorSet arbeitet grundsätlich mit einem full-fetch. All Daten werden via OLE-Variant bereit gestellt. Unglaubliche performance Bremse.

Zeos bietet dir auch den Zugriff über ntwdblib.dll (Protocoll: mssql) oder FreeTDS(diverse Versionen). Nativer Zugriff, jedoch ansi-basierend und bringt auch Tücken mit sich. Das TDS (tabular-data-stream) Protocol läßt keine NClob fetches ohne cast zu(der Grund für die OLE-DB Interpetation). Also schau mal ob du da mehr Erfolg hast und dies deinen Anforderungen entspricht... MSSQL selber ist a bisl, naja leistungsfähig ja, jedoch nur im reiner Forward-Only mode. Nahezu alle RDBM's, außer SQLite, lassen nachträgliches navigiern innerhalb der der Daten-Mengen zu. MSQQL jedoch in keiner Weise, (soweit mir bekannt -> Klärt mich auf und ich bau's ein). Jedoch lädt Zeos dann die Daten erst, wenn du eine weiter Zeile auslesen willst.

Werd jedoc mal reinschauen(ADO), ob da nicht doch irgendwie etwas zu ändern geht und evt. völlig falsch liege -> ADO.

Gruß, Michael
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.580 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: query.open blockiert

  Alt 12. Nov 2013, 06:15
Ein ähnliches Problem habe ich gerade über DataSnap gelöst. Dort kommt dazu, dass ich nicht direkt an die Datenbank herankomme und ausschließlich (AFAIK) komplette DataSets bekomme.

Gelöst habe ich das indem ich mir (es ist ein MS SQL Server) mit DBCC SHOW_STATISTICS die Verteilung der Daten auf der Indexspalte abfrage und dann aus diesem Histogramm einen Abfrageplan erstelle, basierend auf den ermittelten statistischen Werten der aktuellen Verbindungsqualität usw.
Dann frage ich im Thread die einzelnen Pakete ab und hänge diese (in meinem Fall ist das am besten) synchronisiert in die Zieltabelle. Diese wiederum wird dann z.B. für die Anzeige in einer VirtualStringTree benutzt.

In deinem Fall würde es bei einem solchen Vorgehen reichen immer die Datasets mit den einzelnen Paketen weiterzureichen. Und du müsstest die Verarbeitung nicht einmal mit dem Hauptthread synchronisieren, sondern könntest diese auch gleich in Threads machen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#8

AW: query.open blockiert

  Alt 12. Nov 2013, 08:23
Hi, danke fuer eure Antworten.
Ich moechte ungern viel Zeit in die Umstellung der Abfragen investieren, zumal es mit AnyDAC ja auch ohne geht. (eventl. kauf ich die doch fuer mich und compiliere dann nur die finale Version damit).

Bisherige erstmal zufriedenstellende Funktion ist folgende:

Delphi-Quellcode:
    if (FQueryCount = 1) then
      Result.CursorLocation := clUseServer
    else
      Result.CursorLocation := clUseClient;
    if _ReadOnly then begin
      Result.ExecuteOptions := [eoAsyncFetch];
      Result.LockType := ltReadOnly;
    end;
cluseServer blockiert Open nicht, wird aber EXTREM langsam wenn dies innerhalb einer verschachtelten Funktion aufgerufen wird (2 offene Verbindungen ubder die Connection). eoAsyncFetch funktioniert mit cluseClient (Open blockiert nicht) ist aber trotzdem viel langsamer als clUseServer. Ggf. kann ich die Schleifen noch umstellen... Also moeglichst minimaler Aufwand, sonst kann ich gleich das ganze Programm umstellen
  Mit Zitat antworten Zitat
tsteinmaurer

Registriert seit: 8. Sep 2008
Ort: Linz, Österreich
530 Beiträge
 
#9

AW: query.open blockiert

  Alt 12. Nov 2013, 08:47
Vielleicht ist es einfach auch nur das Problem, dass der Snapshot Isolation für READ COMMITTed Transaktionen per Default nicht aktiviert ist, d.h. dass dein lesender Zugriff durch eine noch nicht committete schreibende Transaktion blockiert ist.
  Mit Zitat antworten Zitat
Antwort Antwort


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 04:35 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