Delphi-PRAXiS
Seite 2 von 5     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi ORDER in Unterselect sehr langsam (https://www.delphipraxis.net/141653-order-unterselect-sehr-langsam.html)

dataspider 13. Okt 2009 15:01

Re: ORDER in Unterselect sehr langsam
 
Zitat:

Zitat von hoika
zur Not ne SP erzeugen.
Heiko

So würde ich es auch machen.

Man kann es auch mal so probieren:

SQL-Code:
select p.id
  , (select tb.auftragid from terminal_buchungen tb
     where tb.personalid = p.id and
           tb.buchung = (select max(tbs.buchung) from terminal_buchungen tbs where tbs.personal_id = p.id)
     ) as auftragid
  from personal p
Ungetestet natürlich...
Das Feld Buchung muss dann natürlich eindeutig sein, sonst: multiple rows in singleton select...

[EDIT]für das max muss auch das Feld buchung einen desc Index haben[/EDIT]

Frank

hoika 13. Okt 2009 15:11

Re: ORDER in Unterselect sehr langsam
 
Hallo,

versuche das mal

SQL-Code:
select p1.id, TB1.auftragsid
from personal p1
join TERMINAL_BUCHUNGEN TB1 on TB1.pid=p1.id
where
tb1.buchung in
  (select max(tb2.buchung) from TERMINAL_BUCHUNGEN
   where (tb2.pid=p1.id) and (tb2.auftragsis=tb1.auftragsid));
Ansonsten solltest du mal das SQL-Script der Tabellen
+ ein paar Daten liefern.
Habe keine Lust, das selber zu tippern.


Heiko

Gruber_Hans_12345 13. Okt 2009 17:03

Re: ORDER in Unterselect sehr langsam
 
also das
SQL-Code:
select p.id
  , (select tb.auftragid from terminal_buchungen tb
     where tb.personalid = p.id and
           tb.buchung = (select max(tbs.buchung) from terminal_buchungen tbs where tbs.personalid = p.id)
     ) as auftragid
  from personal p
verwendet
Code:
PLAN (TBS ORDER TERMINAL_BUCHUNGEN_BUCHUNG INDEX (TB_PERSONALID))
PLAN (TB INDEX (TB_BUCHUNG))
PLAN (P NATURAL)
also verwendet alle Indexe, braucht aber nun fast 9 sekunden


dieses Command
SQL-Code:
select p1.id, TB1.auftragid
from personal p1
join TERMINAL_BUCHUNGEN TB1 on TB1.personalid=p1.id
where
tb1.buchung in
  (select max(tb2.buchung) from TERMINAL_BUCHUNGEN tb2
   where (tb2.personalid=p1.id) and (tb2.auftragid=tb1.auftragid));
verwendet PLAN
Code:
PLAN (TB2 ORDER TERMINAL_BUCHUNGEN_BUCHUNG INDEX (TB_PERSONALID, TB_AUFTRAGID))
PLAN JOIN (P1 NATURAL, TB1 INDEX (TB_PERSONALID))
braucht aber fast 14 Minuten ...



ich habe mal folgendes probiert

SQL-Code:
set term #;

execute block
returns (ID INTEGER, MBID INTEGER)
as
declare variable ID1 INTEGER;
begin
  for execute statement
    'select ID FROM PERSONAL' into ID1
  DO begin
    ID = ID1;
    MBID = null;
    execute statement 'SELECT FIRST 1 TB.AUFTRAGID FROM TERMINAL_BUCHUNGEN TB WHERE TB.PERSONALID = ' || ID || ' ORDER BY TB.BUCHUNG DESC' INTO MBID;
    suspend;
  end
end

#
set term ;#
das braucht "nur" mehr 1.5 sekunden, also immer noch nicht wirklich schnell.

Code:
select count(*) from personal -> 268
select count(*) from Terminal_Buchungen -> 321937
Kann es sein, das es nicht mehr schneller geht diese Abfrage?

Gruber_Hans_12345 13. Okt 2009 17:06

Re: ORDER in Unterselect sehr langsam
 
Habe mal folgendes probiert :

SQL-Code:
set term #;

execute block
as
declare variable ID1 INTEGER;
declare I int = 0;
begin
  while (i < 100) do
  begin
    execute statement 'SELECT FIRST 1 TB.AUFTRAGID FROM TERMINAL_BUCHUNGEN TB WHERE TB.PERSONALID = 9 ORDER BY TB.BUCHUNG DESC' INTO ID1;
    i = i + 1;
  end
end

#
set term ;#
wobei ich beim PErsonalID un auf verscheiden filtere ...
Code:
PersonalID=9 -> 2.4 Sekunden (SELECT count(*) FROM TERMINAL_BUCHUNGEN TB WHERE TB.PERSONALID = 9 -> 3 Einträge)
PersonalID=2 -> 20 ms (SELECT count(*) FROM TERMINAL_BUCHUNGEN TB WHERE TB.PERSONALID = 2 -> 400 Einträge)
PersonalID=20 -> 20 ms (SELECT count(*) FROM TERMINAL_BUCHUNGEN TB WHERE TB.PERSONALID = 20 -> 6000 Einträge)
PersonalID=60 -> 2.4 Sekunden (SELECT count(*) FROM TERMINAL_BUCHUNGEN TB WHERE TB.PERSONALID = 60 -> 4 Einträge)
Wie hängt das da zusammen?, je wenige einträge ein personal hat, desto länger dauert die abfrage?!?!?!?!?!

Ich verstehe das absolut nicht mehr

webcss 13. Okt 2009 17:32

Re: ORDER in Unterselect sehr langsam
 
Versuchs mal so:
SQL-Code:
select distinct personal.id as personalid, max(terminal_buchungen.auftragid) as auftragid
from terminal_buchungen inner join personal on personal.id = terminal_buchungen.personalid
group by personalid

Gruber_Hans_12345 13. Okt 2009 17:33

Re: ORDER in Unterselect sehr langsam
 
Zitat:

Zitat von webcss
Versuchs mal so:
SQL-Code:
select distinct personal.id as personalid, max(terminal_buchungen.auftragid) as auftragid
from terminal_buchungen inner join personal on personal.id = terminal_buchungen.personalid
group by personalid

Das Problem ist, dieses SQL liefert falsche Daten, bzw andere Daten,

Ich brauche nicht den größten AuftragID wert sondern den AuftragID Wert von dem datensatz, wo Buchugn am größten ist ...

webcss 13. Okt 2009 17:39

Re: ORDER in Unterselect sehr langsam
 
Zitat:

Zitat von Gruber_Hans_12345
Zitat:

Zitat von webcss
Versuchs mal so:
SQL-Code:
select distinct personal.id as personalid, max(terminal_buchungen.auftragid) as auftragid
from terminal_buchungen inner join personal on personal.id = terminal_buchungen.personalid
group by personalid

Das Problem ist, dieses SQL liefert falsche Daten, bzw andere Daten,

Ich brauche nicht den größten AuftragID wert sondern den AuftragID Wert von dem datensatz, wo Buchugn am größten ist ...

dann so:
SQL-Code:
select distinct personal.id as personalid, terminal_buchungen.auftragid as auftragid, max(terminal_buchungen.buchung) as letzte_buchung
from terminal_buchungen inner join personal on personal.id = terminal_buchungen.personalid
group by personalid, auftragid

omata 13. Okt 2009 19:51

Re: ORDER in Unterselect sehr langsam
 
Leider ist deine Frage nicht ganz präzise formuliert...

Was ist wenn einer Person noch gar kein Auftrag zugewiesen wurde, soll diese dann trotzdem erscheinen mit einem NULL Wert oder nicht?

Falls ja, versuch es so...
SQL-Code:
SELECT p.id, tb.auftragid
FROM personal p
LEFT JOIN (SELECT personalid, auftragid
           FROM terminal_buchungen tb
           WHERE buchung = (SELECT MAX(buchung)
                            FROM terminal_buchungen
                            WHERE auftragid = tb.auftragid)) tb
  ON p.id = tb.personalid
Eventuell auch etwas kompackter...
SQL-Code:
SELECT p.id, tb.auftragid
FROM personal p
LEFT JOIN terminal_buchungen tb
  ON    p.id = tb.personalid
     AND (SELECT MAX(buchung)
          FROM terminal_buchungen
          WHERE auftragid = tb.auftragid) = tb.buchung
Falls nein, versuch es so...
SQL-Code:
SELECT p.id, tb.auftragid
FROM personal p
INNER JOIN terminal_buchungen tb
  ON p.id = tb.personalid
WHERE buchung = (SELECT MAX(buchung)
                 FROM terminal_buchungen
                 WHERE auftragid = tb.auftragid)

hoika 14. Okt 2009 07:14

Re: ORDER in Unterselect sehr langsam
 
Hallo,

warum verwendest du in der SP überhaupt eine Execute Statement ???

SQL-Code:
for select personal.id into :PId do
begin
  select xxx into :AuftragsId
end;

Wo wir beim Plan sind.
Was kommt als Plan bei,
oder anders gefragt: Hat TB.BUCHUNG wirklich einen Desc Index ?

SQL-Code:
SELECT FIRST 1 TB.AUFTRAGID FROM TERMINAL_BUCHUNGEN TB
WHERE TB.PERSONALID = 1 ORDER BY TB.BUCHUNG DESC

Heiko

[edit=mkinzler]SQL-Tags eingefügt Mfg, mkinzler[/edit]

mkinzler 14. Okt 2009 07:19

Re: ORDER in Unterselect sehr langsam
 
Man sollte dann aber ein suspend einfügen


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:29 Uhr.
Seite 2 von 5     12 34     Letzte »    

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