Ich muß in einem Select auf die Tabelle LAGERKARTE alle Karten ermitteln, die
-aktuell einen Bestand <=0
oder
-wo der Bestand unterhalb der Mindestmenge liegt.
Der SQL (a) dafür:
SQL-Anweisung
1: 2: 3:
| SELECT * FROM LAGERKARTE WHERE (LAGERORT BETWEEN '00-000-00' AND '99-999-99') AND ((BESTAND<=0) or (BESTAND<LAGERKARTE.MINDESTMENGE)) and (KEINLAGERTEIL=0) |
Ist okay und läuft auch sauschnell durch (ca. 1,5s, ca 5000 Rows).
Jetzt muss ich obige Menge weiter eingrenzen, in dem ich die Artikelhistorie untersuche (nur der obigen Lagerkarten): Nur wenn in einem angebenen Zeitraum bestimmte Buchungen vorgefallen sind, welche den Bestand<=0 gesetzt haben, soll die obige Lagerkarte angezeigt werden. Der SQL (b) dafür:
SQL-Anweisung
1: 2: 3: 4: 5: 6:
| SELECT ref0 FROM artikelhistorie WHERE artikelhistorie.zeitstempel between '1.1.2007' and '1.9.2007' and artikelhistorie.buchungstyp in (4,5,7,8,9,12,14,16) and artikelhistorie.mengenaenderung is not Null and artikelhistorie.mengenachaenderung<=0 group by artikelhistorie.ref0 |
Ist ebenfalls klar und läuft sauschnell durch (<1s; 114 Sätze).
Soooo, jetzt die Kombination macht mir sorgen
Ach ja: SQL b.ref0 ist der FK auf den PK von SQL a.ref
Ich habe es schon mit Join und Sub-Select ausprobiert, aber die Ausführungszeit beträgt dann jeweils 60 bis 90 Sekunden, in der der SQL Server auf Anschlag läuft und andere Stationen massive Zugriffsprobleme (=Wartezeit) bekommen. Indexprobleme denke ich liegen nicht vor, weil der Plan keine NATURAL aufweist. Außerdem habe ich probeweise mal Indizes auf die verwendeten Felder gelegt, ohne das es den Summer SQL positiv beeinflußte.
Umgangssprachlich brauche ich alle Lagerkarte aus SQL a, deren PK (=Feld ref) auch in der Ergebnisliste von sql.b steht.
Als Subselect sieht das so aus (der IN Operator vermiest mir hier wahrscheinlich das Geschäft, wird der eventuell bei jeder Ergebniszeile durchgeführt?)
SQL-Anweisung
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| SELECT * FROM LAGERKARTE WHERE (LAGERORT BETWEEN '00-000-00' AND '99-999-99') AND ((BESTAND<=0) or (BESTAND<LAGERKARTE.MINDESTMENGE)) and (KEINLAGERTEIL=0) and ref in (SELECT ref0 FROM artikelhistorie WHERE artikelhistorie.zeitstempel between '1.1.2007' and '1.9.2007' and artikelhistorie.buchungstyp in (4,5,7,8,9,12,14,16) and artikelhistorie.mengenaenderung is not Null and artikelhistorie.mengenachaenderung<=0 group by artikelhistorie.ref0 ORDER BY LAGERORT ASC |
Als Ergebnismenge erwarte ich ungefähr 60 bis 80 Rows.
Hat da noch jemand einen Tip, um dem SQL bzw. dem Optimzer/Planer auf die Sprünge zu helfen?