Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi delete mit join (https://www.delphipraxis.net/91820-delete-mit-join.html)

hoika 10. Mai 2007 13:29

Datenbank: FB • Version: 1.5 • Zugriff über: egal

delete mit join
 
Hallo #,

folgender Code erzeugt einen Fehler (join wird angemeckert)
SQL-Code:
Delete From DataFoxInput_Details1
Join DataFoxInput on DataFoxInput.Id=DataFoxInput_Details1.DataFoxInputId
Where
  (DataFoxInput.TheDate=:CheckDate) And
  (DataFoxInput_Details1.Flag Is Null) And
  (DataFoxInput_Details1.CardNo Is Null)
Ich versuche einen Detail-Eintrag (Tabelle: DataFoxInput_Details1) eines bestimmten Tages
zu löschen, der Tag steht aber nur in der Mastertabelle (DataFoxInput.TheDate).
Bekomme ich das ohne "where in " hin ?


Heiko

mkinzler 10. Mai 2007 14:02

Re: delete mit join
 
Nimm einen Subselect

hoika 10. Mai 2007 14:19

Re: delete mit join
 
Hallo,

etwa so ?
ist die 2. Detail-Tabelle, aber ähnlich aufgebaut.


Delphi-Quellcode:
SQL.Add('Delete From DataFoxInput_Details2');
SQL.Add('Where');
SQL.Add(' (DataFoxInput_Details2.DataFoxInputId');
SQL.Add('    In (Select DataFoxInput.Id From DataFoxInput');
SQL.Add('        Where DataFoxInput.TheDate=:CheckDate)');
SQL.Add(' )');
Das geht FB sowas von in die Knie.

Ein
select * from DataFoxInput_Details2
Where
(DataFoxInput_Details2.DataFoxInputId
In (Select DataFoxInput.Id From DataFoxInput
Where DataFoxInput.TheDate='8.12.2007'))

braucht 50 Sekunden (lokaler SQL-Server)

Plan:
PLAN (DATAFOXINPUT INDEX (RDB$PRIMARY153))
PLAN (DATAFOXINPUT_DETAILS2 NATURAL)


Das hier im Select natürlich ein Join besser wäre,
ist klar, es geht aber ja am das delete.

Was is nu kaputt ?
Indizes sind natürlich deauf.
die Details2 Tabelle hat etwa 2.7 Mio Einträge,
davon ~ 30000 vom 8.12.


Heiko

hoika 10. Mai 2007 14:27

Re: delete mit join
 
erledigt:
die folgenden SP braucht 3 Sekunden,
das reicht.


Heiko
SQL-Code:

CREATE PROCEDURE SP_DATAFOX_DELETEDETAILS2 (
    THEDATE DATE)
AS
DECLARE VARIABLE iCurId Integer;
begin
  for select det2.id from DataFoxInput_Details2 det2
  join
    DataFoxInput on DataFoxInput.Id = det2.DataFoxInputId
  where
    DataFoxInput.theDate = :TheDate
  into :iCurId do
  begin
    Delete From DataFoxInput_Details2 Where Id=:iCurId ;
  end

  Suspend;
end


nächster Test

SQL-Code:
select count(*) from DataFoxInput_Details2 det2_1
Where
  det2_1.id in
 
  (
    select
      det2_2.id from DataFoxInput_Details2 det2_2
    join
      DataFoxInput on DataFoxInput.Id = det2_2.DataFoxInputId
    where
      DataFoxInput.theDate = '8.12.2007'
  )
ergibt 30 Sekunden.

Ich werde jetzt mal ne SP schreiben.


Heiko

omata 10. Mai 2007 19:20

Re: delete mit join
 
Hallo hoika,

was spricht gegen folgende Variante...
SQL-Code:
DELETE FROM DataFoxInput_Details1
WHERE DataFoxInputId IN (SELECT id
                         FROM DataFoxInputId
                         WHERE TheDate = :CheckDate)
  AND Flag IS NULL
  AND CardNo IS NULL
oder auch...
SQL-Code:
DELETE FROM DataFoxInput_Details1
WHERE EXISTS (SELECT *
              FROM DataFoxInputId
              WHERE TheDate = :CheckDate
                AND id = DataFoxInputId)
  AND Flag IS NULL
  AND CardNo IS NULL
Gruss
Thorsten

hoika 10. Mai 2007 19:53

Re: delete mit join
 
Hallo,

Laufzeit > 1 min pro Query spricht dagegen.
Das gleiche in einer SP -> 2 sec.


Heiko

TBx 10. Mai 2007 20:09

Re: delete mit join
 
schneller gehen sollte es so:

SQL-Code:
CREATE PROCEDURE SP_DATAFOX_DELETEDETAILS2 ( 
    THEDATE DATE)
AS
DECLARE VARIABLE iCurId Integer;
begin
  for select id from DataFoxInput
        where theDate = :TheDate
       into :iCurId
  do
  begin
    Delete From DataFoxInput_Details2 Where DataFoxInputId = :iCurId ;
  end
end
Der Join, den Du hier drin hattest, brachte keine Vorteile, im Gegenteil, es wurden mehr Datensätze selektiert.

Hope it helps

onlinekater

[Edit] Das überflüssige SUSPEND entfernt. Das wird hier nicht gebraucht, da die Stored Procedure keine Rückgabewerte hat. Man sollte es hier nicht verwenden. [/Edit]

omata 10. Mai 2007 22:11

Re: delete mit join
 
@hoika:

Ok, wenn das so ist. Ich habe das gerade mal ausprobiert und 160000 Datensätze werden bei mir mit der EXISTS-Variante in 5 Sekunden gelöscht. Vermutlich hast du wesentlich mehr Datensätze.

Gruss
Thorsten

hoika 11. Mai 2007 09:26

Re: delete mit join
 
Hallo,

danke noch mal an beide,
ohne join ist es noch ein "bissel" schneller ;)

und das mit dem Exists kannte ich so noch gar nicht *wunder*
ist in 1 sec durch ...

Soll ich die sp jetzt wegwerfen ???


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz