Abfrage beschleunigen



  • Hallo zusammmen!

    Hat jemand einen Tipp für mich, wie ich folgende Abfrage beschleunigen kann?
    In der relevanten Tabelle habe sind aktuell 460 Einträge, was an sich ja noch keine Menge ist. Dennoch dauert die Abfrage inzwischen ca. 10-15 Sekunden.

    for (int n = 0; n < dg.Rows.Count; n++)
    {
        // Prüfen ob WE komplett.
        if (Convert.ToBoolean(dg["WEabgeschlossen", n].Value) == true)
        {
             dg["WEabgeschlossen", n].Style.BackColor = Color.Green;
        }
        else
        {
            weTeilweiseAbgeschlossen = WareneingangKomplett(Convert.ToInt32(dg["idBestellungEK", n].Value));
            if (weTeilweiseAbgeschlossen)
            {
                dg["WEabgeschlossen", n].Style.BackColor = Color.Yellow;
            }
            if (!weTeilweiseAbgeschlossen)
            {
                dg["WEabgeschlossen", n].Style.BackColor = Color.Red;
            }
        }             
    }
    
    public  bool WareneingangKomplett(int iBestellungEkId)
    {
        try
        { 
            using (entity1 ctx = new entity1())
            {
                var query = (from w in ctx.tblwareneingang_einzelheiten
                             where w.bestellungen_ekId == iBestellungEkId
                             select w).ToList();
    
                if (query != null)
                {
                    foreach (tblwareneingang_einzelheiten we in query)
                    {
                        // falls abgeschlossen.
                        if (we.liefermengeAbgeschlossen)
                            return true;
                        else
                        // falls zumindest Eintrag existiert.
                        if (we.gelieferteMenge != 0)
                            return true;
                    }
                            return false;
                }
                else
                    return false;
             }
        }
        catch (Exception ex)
        {
             MessageBox.Show("Fehler: " + ex.Message);
             return false; ;
        }
    }
    


  • Niemand eine Idee??? 😕 😕



  • Hi,

    schau doch mal mit einem Profiler, wo genau der Flaschenhals im Code ist und wenn es wirklich das Query ist, dann schaust du welches Query an den SQL Server abgesetzt wird. Damit gehst du auf den SQL Server und prüfst den Ausführungsplan - möglicherweise fehlen Indizes.

    Viele Grüße
    KaPtainCugel



  • dein WareneingangKomplett wir dann 460 mal aufgerufen - das ist wirklich sehr ungeschickt - warum machst du nicht alles zusammen in einem Query (mit Join)?

    aus welchem Query ergibt sich der dg.Rows.Count?

    kannst du mal die relevanten Tabellen/Felder (und bitte auch nur diese - nicht alle) posten - damit man mal eine idealere SQL-Abfrage als Beispiel bauen kann



  • Vermutlich hast du auf bestellungen_ekId keinen Index.
    Und vermutlich wäre es nochmal einiges schneller wenn du die ganze Funktion WareneingangKomplett im SQL Server machst und als berechnete Spalte mitgibst.
    (-> z.B. View statt Table aufmachen)



  • und dann holst du dir in der WareneingangKomplett auch noch alle Felder um 2 davon zu pruefen - auch nicht wirklich sinnvoll

    ich denke du kommst mit einem einzigen Query auf deine Green/Yellow/Red-Aussage - ohne so viel Schleifen und ifs in C# - lass die Datenbank auch ihre Fähigkeiten nutzen



  • select 
      idBestellungEK,
      case WEabgeschlossen
        when 1 then 0 -- gruen
        when 0 then 
        (
          select 
           case when exists 
           (
             select 
               1
             from 
               tblwareneingang_einzelheiten 
             where 
               bestellungen_ekId = idBestellungEK
               and (liefermengeAbgeschlossen = 1 or gelieferteMenge != 0)
           ) then 1 -- gelb
             else 2 -- rot
           end
        )
      end as abgeschlossen_zustand
     from bestellungen
    

    das Ergebnis

    idBestellungEK abgeschlossen_zustand
    1 1
    2 2
    3 0
    

    fuer diese Tabellen

    tblwareneingang_einzelheiten

    (int)bestellungen_ekId (int)teilmenge (bit)liefermengeAbgeschlossen (int)gelieferteMenge
    1 0 1 100
    1 1 0 0
    1 2 1 200
    2 0 0 0
    2 1 0 0
    3 0 1 0
    3 1 1 0
    3 2 1 0
    

    und

    bestellungen

    (int)idBestellungEK (bit)WEabgeschlossen
    1 0
    2 0
    3 1
    

    geht es noch kürzer?



  • public  bool WareneingangKomplett(int iBestellungEkId)
    {
        try
        { 
            using (entity1 ctx = new entity1())
            {
                bool result = ctx.tblwareneingang_einzelheiten.Any( s =>
                                s.ekId == iBestellungEkId &&
                              ( s.liefermengeAbgeschlossen ||
                                s.gelieferteMenge != 0 ) );
    
                return result;
             }
        }
        catch (Exception ex)
        {
             MessageBox.Show("Fehler: " + ex.Message);
             return false; ;
        }
    }
    

    oder vorher die Tabelle materialisieren:

    var query = (from w in ctx.tblwareneingang_einzelheiten
                   where w.bestellungen_ekId == iBestellungEkId &&
                       ( w.liefermengeAbgeschlossen || w.gelieferteMenge != 0 )
                   select new { ID = iBestellungEkId } ).Distinct()
                   .ToDictionary( s => s.ID, s => true );
    

    und später abfragen

    weteilweiseAbgeschlossen = query.ContainsKey(
                                    Convert.ToInt32(dg["idBestellungEK", n].Value) )
    


  • @SolidOffline - also meine Select kommt direkt auf das gruen,rot,gelb-Ergebnis - aber ich habe auch einfach Annahmen über seinen übergeordneten 460-Ids-Query gemacht 🙂



  • @Gast3

    select
    idBestellungEK,
    case WEabgeschlossen
    when 1 then 0 -- gruen
    when 0 then
    (
    select
    case when exists
    (
    select
    1
    from
    tblwareneingang_einzelheiten
    where
    bestellungen_ekId = idBestellungEK
    and (liefermengeAbgeschlossen = 1 or gelieferteMenge != 0)
    ) then 1 -- gelb
    else 2 -- rot
    end
    )
    end as abgeschlossen_zustand
    from bestellungen

    Super Sache! Funktioniert und läuft nun auch richtig schnell!! Herzlichen Dank für Deine Hilfe!



  • mir fehlte bei deinem Beispiel leider noch der Query mit dem du auf die 460 Rows am Anfang gekommen bist sonst hätte ich da noch weiter eingegrenzt - mein Select nimmt jetzt einfach alle

    kann du noch hinschreiben welche Wheres zu deinen 460 Einträgen führen - oder waren es da auch einfach nur alle aus deinem Bestellungen-Table?


Anmelden zum Antworten