Announcement

Collapse
No announcement yet.

Interbase Cursor -> FETCH

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Interbase Cursor -> FETCH

    Von: Jörg Kaschkat
    [email protected]

    An : Andreas Kosch

    Sehr geehrter Herr Kosch!

    Bei mir kommt der Interbase-SQL-Server 5.6 auf Linux zum Einsatz.
    Die Clients werden unter NT, Solaris und Linux betrieben. Auf NT
    werden Abfragen mit der BDE realisiert. Unter Linux und Solaris
    wird mit embedded SQL gearbeitet. IB 5.6 hat eine FETCH-Logik, die
    nur unidirektional funktioniert. Für Ergebnismengen, die komplett
    zwischengespeichert werden können, ist das kein Problem. Auf dem
    Server werden riesige Mengen von Messwerten gespeichert. Ergebnis-
    mengen von Abfragen können des öfteren mehr als 100000 Zeilen sein.
    Mit einem serverseitigen Cursor ist nur eine Vorwärtsbewegung
    möglich. In den Handbüchern von Interbase wird für eine Rückwärts-
    bewegung in der Ergebnismenge folgender Vorschlag gemacht:

    1. Aktuelle Zeilennummer merken.
    2. Cursor (Abfrage) schließen.
    3. Cursor (Abfrage) neu erzeugen und abschicken.
    4. FETCH bis zum gewünschen Bereich ohne Speicherung ausführen.
    5. FETCH mit Speicherung ausführen.

    Diese Art der Problemlösung funktioniert fehlerfrei, ist jedoch bei
    einigen Konstellationen sehr langsam:

    Man hat auf dem Client nur einen kleinen Puffer im Programm vorgesehen
    und befindet sich relativ nah am Ende der Ergebnismenge. Eine Rückwärts-
    bewegung in der Ergebnismenge, die sich auch nicht mehr im programm-
    eigenen Puffer befindet, hat extrem viele FETCH-Aufrufe zur Folge, nur
    um den Cursor an eine gewünschte Stelle zu positionieren. Auch die
    Belastung des Netzes ist sehr hoch.

    Meine Frage nun: Gibt es eine Möglichkeit eine Abfrage zu erzeugen und
    mit dem Cursor einen "Sprung vorwärts" zu machen, um die vielen FETCH-
    Zugriffe zum Positionieren zu vermeiden ?

    Mit freundlichem Gruß

    J.Kaschkat

  • #2
    Hallo,

    den Einsatz von Embedded SQL kenne ich nur vom Lesen in den InterBase-Handbüchern her - für eine Delphianer ist Embedded SQL kein Thema. Allerdings sollte der folgende Lösungsvorschlag universell nutzbar sein. Das Problem liegt dabei darin, das unnötige Daten zum Client transportiert werden müssen (hohe Netzlast, Zeitverzögerung). Wenn der InterBase in seiner aufgebauten Ergebnismenge nur vorwärts laufen kann, bedeutet das nicht, das er alle Zwischenschritte zum Client schicken muss. Die folgende <b>Stored Procedure</b> liefert zum Beispiel nur die letzten x Datensätze zurück, so das die unerwünschte Nebenwirkung der hohen Netzwerkbelastung beseitigt ist:
    <pre>
    /* SQL-Explorer-Script */
    /* Anw.-Begrenzer ist ^ */
    CREATE PROCEDURE GETLASTXKUNDEN (KUNDENID INTEGER, ROWS INTEGER)
    RETURNS (VORNAME CHAR(35),NACHNAME CHAR(35))
    AS
    DECLARE VARIABLE iREC_COUNT INTEGER;
    DECLARE VARIABLE iCOUNT INTEGER;
    DECLARE VARIABLE iSTART_FROM INTEGER;
    BEGIN
    /* Wie viele Daten sind vorhanden? */
    SELECT COUNT(*)
    FROM kundenimp
    INTO :iREC_COUNT;
    /* Wo anfangen? */
    IF (ROWS >= iREC_COUNT) THEN
    iSTART_FROM = 1;
    ELSE
    iSTART_FROM = iREC_COUNT - ROWS + 1;
    /* Counter setzen */
    iCOUNT = 0;
    /* SQL-Abfrage aufbauen */
    FOR SELECT kundenid, vorname, nachname
    FROM kundenimp
    ORDER BY kundenid
    INTO :kundenid, :vorname, :nachname
    DO
    BEGIN
    iCOUNT = iCOUNT + 1;
    IF (iCOUNT >= iSTART_FROM) THEN
    BEGIN
    SUSPEND;
    END
    END
    END
    ^
    </pre>

    Erst dann, wenn der <i>iCount</i>-Wert mindestens gleich gross wie der als Parameter übergebene "Startwert" ist, werden die Daten zum Client übertragen. Die Stored Procedure "überspringt" somit die ersten x Datensätze

    Comment


    • #3
      Hallo,
      wir sind dabei unsere Anwendung auf Client/Server-Basis umzustellen. Dabei haben wir den Interbase-Server mit Delphi 5 und BDE bzw. Interbase-Express getestet.
      Der gravierendste Unterschied zwischen Interbase und dem MS-SQL-Server bzw. Sybase liegt im FETCH-Befehl. Interbase erlaubt wie oben beschrieben nur ein FETCH NEXT und nicht wie MS-SQL-Server und Sybase ein FETCH [NEXT, FIRST, PRIOR, LAST, ABSOLUTE, RELATIVE].
      Dies ist insbesonders bei großen Ergebnismengen ein Zeitproblem mit enormer Netzbelastung. Die von Herrn Kosch genannte Lösung ist sicherlich für den Einzelfall ein aktzeptabler Weg.
      Bei unseren Tests mit der BDE und auf/absteigenden Indizierungen konnten wir noch akzeptable Werte messen.
      Der Zugriff auf das letzte Element (bei großen Ergebnismengen) mit Interbase-Expresskomponenten ist nicht aktzeptable.

      Meine Frage zu Interbase :
      - Gibt es von Interbase Bestrebungen in einer zukünftigen Version den FETCH-Befehl zu erweitern ?
      - Wurde solche oder ähnliche Anforderung bereits an Interbase gestellt

      Comment


      • #4
        Hallo,

        das grundlegende Problem bei allen SQL-Datenbanken liegt darin, die Ergebnismenge einer SELECT-Abfrage so klein wie möglich zu halten. Jede Begrenzung der zum Client zu übertragenden Daten greift an dieser Stelle zu spät, da die Ressourcenbelastung durch die umfangreiche Ergebnismenge auf der Server-Seite in jedem Fall auftritt. Daher ist zum Beispiel ein SELECT TOP 10 ... FROM...-Aufruf (MS SQL Server 7) zwar für den Entwickler einfach (er begrenzt das Ergebnis auf die ersten 10 Datensätze), für den Server jedoch nicht. Da SQL-Datenbanken mengenorientiert arbeiten, muss der Server die vollständige Ergebnismenge aufbauen - erst am Ende steht fest, welcher Datensatz welche Position einnimmt (zumal wenn GROUP BY-Klauseln etc. verwendet werden).

        Aus diesem Grund arbeiten die mengenorientierten SQL-Datenbanken völlig anders als die datensatzorientierten ISAM-Datenbanken. Die Funktionen zum "Browsen" im Datenbestand benötigt man nur dann, wenn die eigenen Anwendung ihren Aufbau <b>nicht</b> den Anforderungen von SQL-Datenbanken anpasst. Wenn man bedenkt, das MS den SQL Server 7 auch als Backend für MS ACCESS empfiehlt, wird klar, das dieser Server Funktionen für das "Browsen" in der Ergebnismenge benötigt.

        Der InterBase ist an dieser Stelle deutlich näher am SQL-Standard, so das die VCL das Browsen simuliert (indem die Ergebnismenge zum Client transportiert wird). Und dies hat immer dann keine gravierenden Nachteile, wenn die Ergebnismenge klein gehalten wird.

        P.S: Auch unter ADO wird von MS für SQL-Datenbanken das <i>Client-side Recordset</i> propagiert (so das sich ADO an dieser Stelle wie die Kombination InterBase+VCL verhält)

        Comment

        Working...
        X