Thema: Delphi Geschwindigkeitsproblem

Einzelnen Beitrag anzeigen

Robert_G
(Gast)

n/a Beiträge
 
#3

Re: Geschwindigkeitsproblem

  Alt 6. Aug 2005, 18:54
Zitat von marabu:
Dazu gibt es in Interbase SQL den Befehl SUSPEND. Durchforste mal dein Handbuch zum Thema Stored Procedure - vielleicht kann Oracle das ja auch?
Es gibt keine Selectable Procedure in Oracle. (Und wird sie in den nächsten 20 Jahren wohl auch nicht geben )

@Andreas
Dumme Frage, aber hast du wirklich Indizes auf den Feldern?
Bei migrierten DBs von Ora<9 hat man das "Problem" dass Ora9 nicht mehr automatische Indizes auf Foreign Keys vergibt.
Außerdem kommt es nur noch bescheiden mit nicht/schlecht normalisierten Daten klar.
Die JOIN Syntax ist bei Ora übrigens nicht nötig, da der Optimizer genau erkennt wie du wo welche Tabellen verknüpft.
Bei 30 Tabellen in der From clause wird zwar der erste Lauf durch die Optimierung langsamer, aber effektiv macht es sich nicht wirklich bemerkbar.

Was du machen könntest, wäre diese Liste mit Werten als Array an ein Package zu übergeben. (wenn es immer eine Liste von x =1 or X = 2 or X = 3,... ist)
Dann nimmst du als rückgabewert wieder eine Liste von Werten. Auf die Art ersparst du dir sämtliche round trips da nur einmal Eine Liste hingeschickt und eine zurückgeschickt werden muss.

Wenn du DOA benutzt, kann du diese Oracle Objekte an deine Delphi Applikation binden. (siehe: TOracleObject, TOracleQuery.SetComplexVariable, TOracleQuery.GetComplexVariable)

ich habe mir eben zum Testen diese Beispieltabelle angelegt:
SQL-Code:
create table JbgTable
(
  ID INTEGER not null,
  NAME VARCHAR2(255),
  FIRSTNAME VARCHAR2(255)
);
alter table JBGTABLE
  add constraint JBGTABLE_PK primary key (ID)
  using index;

Jetzt braucht man einen Objekttypen, der einem Datensatz entspricht:
SQL-Code:
create or replace type TJbgItem as object
(
  Id Integer,
  Name VarChar(255),
  FirstName VarChar(255)
)
Die Liste, die man zurückbekommen will:
create or replace type TJbgItemList as table of TJbgItem; Die Liste, die man der Funktion übergibt:
create or replace type TIntegerList as table of Integer; Das Package[1]:
SQL-Code:
create or replace package JbgTest is

  function FetchValues(aIds in TIntegerList) return TJbgItemList;

end JbgTest;

SQL-Code:
create or replace package body JbgTest is
  cursor getRecords(iId in Integer) is
    SELECT TJbgItem(iId, Name, FirstName)
    FROM JbgTable t
    WHERE t.Id = iId;

  function FetchValues(aIds in TIntegerList) return TJbgItemList is
    result TJbgItemList := TJbgItemList();
  begin

    result.Extend(aIds.Count);

    for i in aIds.First .. aIds.Last loop
      open getRecords(aIds(i));

      FETCH getRecords
        INTO result(i);

      close getRecords;

    end loop;

    return result;
  end;

end JbgTest;
[1] eine einfache Funktion würde auch reichen, bei Packages wird aber wiederholter Zugriff auf einen darin liegenden Cursor etwas schneller.

Aus Mangel an DOA hier zu Hause habe ich es mit einem simplen PL/SQL Script getestet:
SQL-Code:
declare
  Ids TIntegerList := TIntegerList();
  result TJbgItemList;
begin
  Ids.Extend(:Records);

  for i in Ids.First .. Ids.Last loop
    Ids(i) := dbms_Random.Value(:MinValue, :MaxValue);
  end loop;

  result := JbgTest.FetchValues(Ids);

  :Returned := result.Count;
end;
Die Tabelle habe ich mit 2*10^6 zufälligen VorName/NachName Kombis füllen lassen.
Wenn ich :Records 1000 übergebe (Wodurch 1000 zufallige IDs gesucht werden) braucht er keine 150 Millisekunden.
Und das obwohl mein kleiner "Server" nur ein Virtual Server auf einer kleineren Maschine ist!

Hihi, endlich mal wieder etwas mit Ora gespielt.
  Mit Zitat antworten Zitat