Entwickler-Ecke

Datenbanken - firebird view und stored procedures Geschwindigkeit


Josef-B - So 09.01.11 21:39
Titel: firebird view und stored procedures Geschwindigkeit
Hallo,

nachdem ich nun schon einige Zeit mit firebird arbeite, hab ich mich nun doch
mal an die stored procedures rangetraut, vorher hatte ich mit einem view gearbeitet.

Es geht um die Abfrage von Artikeln aus einer Datenbank mit ungefähr 800.000 Sätzen

Hierzu hatte ich ein view wie folgt


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
CREATE VIEW V_ARTIKELABFRAGE(
    ARTIKELNUMMER,
    EAN,
    ARTIKELBEZEICHNUNG,
    ARTIKELNUMMER_LIEFERANT,
    BASIS_ME,
    LIEFERANT,
    LIEFERANT_NAME)
AS
select e.Artikelnummer,c.ean,a.Artikelbezeichnung,
        e.Artikelnummer_Lieferant,a.Basis_ME,
        e.Lieferant,e.Lieferant_Name from
    artis_Einkauf e

inner join artis_artikelstamm a
    on e.artikelnummer = a.artikelnummer

 inner join artis_EAN c
    on e.artikelnummer = c.artikelnummer
;


Als Abfrage dann:


SQL-Anweisung
1:
Select * from v_Artikelabfrage where ean = :EAN                    


Diese Abfrage dauert mit IBEXPERT so ungefähr 6 Sekunden !

Nun hab ich das ganze in eine stored-Procedure gepackt
mit dem Parametet EAN als Input Parameter und ich dachte es
geht schneller. Aber leider ist in der Geschwindigkeit
kein messbarer Unterschied.

Kann man da noch was machen?

Moderiert von user profile iconKlabautermann: Delphi- durch SQL-Tags ersetzt.


Andreas Schilling - Mo 10.01.11 08:45

Mit einer SP sollte es schneller zu machen sein wenn auf Tabelle artis_EAN ein Index auf Spalte EAN liegt und auf den anderen beiden Tabellen ein Index auf Artikel. Wie sieht die Stored Procedure den aus?

Gruß Andreas


Josef-B - Mo 10.01.11 09:52

Ich hatte die Indices nicht gesetzt.

Hab ich jetzt gemacht. Muss ich auch foreign keys setzen?

Leider geht die stored proc immer noch nicht schneller.

Interessanterweise geht die View-Abfrage geht jetzt super schnell.

Hier die Stored Procedure


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
CREATE OR ALTER PROCEDURE PROC_Artikel_sel (
    p_ean bigint)
returns (
    artikelnummer bigint,
    ean varchar(13),
    artikelbezeichnung varchar(40),
    artikelnummer_lieferant varchar(15),
    basis_me varchar(4),
    lieferant bigint,
    lieferant_name varchar(30))
as
begin
  /* Procedure Text */
  for select e.artikelnummer, c.ean, a.Artikelbezeichnung,
            e.artikelnummer_lieferant, a.Basis_ME,
            e.Lieferant,e.Lieferant_Name
  from artis_einkauf e

  inner join artis_artikelstamm a
    on e.artikelnummer = a.artikelnummer

  inner join artis_ean c
    on e.artikelnummer = c.artikelnummer

  where c.ean = :P_EAN

  into :artikelnummer, :EAN, :artikelbezeichnung, :Artikelnummer_Lieferant,
        :Basis_me,:Lieferant,:Lieferant_Name

  do
  begin
    suspend;
    end
end


Moderiert von user profile iconKlabautermann: Delphi- durch SQL-Tags ersetzt.


Andreas Schilling - Mo 10.01.11 11:36

Problem beim View: er holt erst einmal alle Daten der ganzen Tabelle um nach dem Kriterium EAN filtern zu können.
Ansatz meiner Procedure:
1) EAN in Artikelnummer umwandeln
2) zu Artikelnummer Stammdateninfos holen (Bezeichnung, ME)
3) jetzt in einer Schleife Bewegungsdaten des Artikel holen


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
CREATE OR ALTER PROCEDURE PROC_Artikel_sel (
    p_ean bigint)
returns (
    artikelnummer bigint,
    ean varchar(13),
    artikelbezeichnung varchar(40),
    artikelnummer_lieferant varchar(15),
    basis_me varchar(4),
    lieferant bigint,
    lieferant_name varchar(30))
as
begin
  /* Procedure Text */
  for select Artikelnummer from artis_ean
      where EAN =:EAN into :Artikelnummer
  do begin
    select Artikelbezeichnung, Basis_ME from artis_artikelstamm 
    where Artikelnummer = :Artikelnummer 
    into :artikelbezeichnung, :Basis_me;

    for select artikelnummer_lieferant, Lieferant, Lieferant_Name
        from artis_einkauf where Artikelnummer = :Artikelnummer
        into :Artikelnummer_Lieferant, :Lieferant,:Lieferant_Name
    do begin
      suspend;
    end
  end
end


Moderiert von user profile iconKlabautermann: Delphi- durch SQL-Tags ersetzt.


Josef-B - Mo 10.01.11 15:29

danke, das ist ein guter Ansatz, werd ich probieren


Tankard - Mo 10.01.11 18:28

EAN als VARCHAR??

die EAN kann doch garkeine Buchstaben und Sonderzeichen enthalten.

http://de.wikipedia.org/wiki/European_Article_Number