Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Größe der Query reduzieren

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von kwakz, 30 September 2013.

  1. kwakz

    kwakz Aktiver Benutzer

    Hallo zusammen,

    für eine Ventilproduktion werden die Produktionsdaten in einer Datenbank abgelegt. In Tabelle 1 gibt es die Zuordnung einer ID zu Produktionsdatum, Ventiltyp, Teilbewertung und anderen Punkten. In verschiedenen anderen Tabellen bekomme ich über die ID Informationen über Messwerte, Parametersätze und dergleichen.

    Um mir jetzt meine Messwerte herauszusuchen, mache ich nunächst eine abfrage, welche IDs in einem bestimmten Zeitraum produziert wurden. Diese IDs verknüpfe ich dann mit einem 'OR' und suche dann in den anderen Tabellen. Das funktioniert bei kurzen Zeiträumen auch ganz gut. Mache ich den Zeitraum aber länger, dann bekomme ich zwar noch meine IDs für den Zeitraum, bei der Abfrage der Messwerte kommt aber die Fehlermeldung:

    Ich nehme an, dass ich einfach versuche zu viele IDs miteinander zu verknüpfen ... ich habe auch schon irgendwo die Information gefunden, dass die Anfrage nicht mehr als 65000 Zeichen haben darf (was bei einer Produktion von mehreren tausend Ventilen am Tag aber ganz schnell zusammen kommt).

    Jetzt die Frage: Wie kann ich die Anfrage vereinfachen? Gibt es zum Beispiel eine Möglichkeit, dass ich mir die gefundenen IDs in einer Liste ablege und bei der Abfrage der Messwerte dann sage: "Tu das für alle IDs, die in der Liste stehen"?

    Mfg Daniel
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Du kannst das zu einem JOIN umschreiben oder zu einem Subselect. Versuch es mal.

    Also z.B. select bla, fasel from table2 where id in (select id from foobar where datum = ...)
     
  3. ukulele

    ukulele Datenbank-Guru

    Solange nicht zu jeder ID ein eigenes Resultat geliefert werden soll (bei OR Verknüpfungen wird ja auch nur eine Abfrage erstellt) sollte das auf jedenfall mit Join oder Subselect gehen. Wenn du es nicht hinbekommst musst du die Abfragen mal posten.

    Die OR Variante dürfte aber eigentlich auch nicht viel langsammer sein, eventuell besteht hier auch noch ein anderes Problem.
     
  4. kwakz

    kwakz Aktiver Benutzer

    Hallo zusammen,

    schon mal vielen Dank für die Antworten. Ihr habt mir schon mal ein Stück weiter geholfen. Allerdings hilft mir das noch nicht bis ganz an's Ziel: Zwischendurch bearbeite ich meine IDs auch nach Gesichtspunkten, die so nicht in der Datenbank zu finden sind. Danach muss ich quasi mit den OR-verknüpften IDs die nächsten Abfragen machen. Habt Ihr dafür auch eine Lösung für mich?

    Mfg Daniel
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Das klingt abentuerlich ...


    Geht es besser, wenn Du die ID's einfach in eine neue Tabelle schreibst und damit arbeitest?
     
  6. ukulele

    ukulele Datenbank-Guru

    Man kann auch statt ID = 1 OR ID = 2 mit ID IN (1,2) arbeiten aber an der eigentlichen Geschwindigkeit dürfte das nicht viel ändern. Interessant dürfte es bei der Anzahl der IDs im Query und in der Tabelle werden und ob es einen Index auf die ID Spalte gibt.
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Depends.

    Das kann durchaus in unterschiedlichen Plänen ausarten:

    Code:
    test=*# explain select * from foo where id=1 or id=2 or id=3;
      QUERY PLAN
    --------------------------------------------------------------------------
     Bitmap Heap Scan on foo  (cost=13.05..23.68 rows=36 width=4)
      Recheck Cond: ((id = 1) OR (id = 2) OR (id = 3))
      ->  BitmapOr  (cost=13.05..13.05 rows=36 width=0)
      ->  Bitmap Index Scan on idx1  (cost=0.00..4.34 rows=12 width=0)
      Index Cond: (id = 1)
      ->  Bitmap Index Scan on idx1  (cost=0.00..4.34 rows=12 width=0)
      Index Cond: (id = 2)
      ->  Bitmap Index Scan on idx1  (cost=0.00..4.34 rows=12 width=0)
      Index Cond: (id = 3)
    (9 rows)
    
    test=*# explain select * from foo where id in (1,2,3);
      QUERY PLAN
    --------------------------------------------------------------------
     Bitmap Heap Scan on foo  (cost=5.03..15.53 rows=36 width=4)
      Recheck Cond: (id = ANY ('{1,2,3}'::integer[]))
      ->  Bitmap Index Scan on idx1  (cost=0.00..5.02 rows=36 width=0)
      Index Cond: (id = ANY ('{1,2,3}'::integer[]))
    (4 rows)
    
    

    Andreas
     
  8. kwakz

    kwakz Aktiver Benutzer

    Da hab ich mich vielleicht nicht ganz richtig ausgedrückt. Es ist halt so: Ich reduziere meine IDs in mehreren Schritten, wobei die Gesichtspunkte für diese Schritte in verschiedenen Tabellen abgelegt sind. Als Beispiel:

    1. Nimm alle IDs, die innerhalb eines bestimmten Zeitraums gebaut wurden und die Bewertung OK bekommen haben.
    2. Aus diesen IDs sortiere die aus, die nicht im ersten Durchlauf auf der Anlage sind, sondern schon nachbearbeitet wurden
    3. Aus den resultierenden IDs sortiere die aus, die nicht in einem bestimmten Testmodul getestet wurden.

    Im Prinzip steht für jeden Punkt die Information in einer anderen Tabelle. Die Verarbeitungsschritte mache ich in einem LabVIEW-Programm, was dann mit den reduzierten IDs wieder auf die nächste Tabelle zugreifen muss.

    Für die Datenbank selbst habe ich leider nur Leserechte ... damit fällt das Anlegen einer neuen Tabelle flach.
     
  9. ukulele

    ukulele Datenbank-Guru

    Und hast du schon eine Abfrage noch dem Motto
    Code:
    SELECT   *
    FROM   tabelle
    WHERE   ID IN (   SELECT   ID
             FROM   tab_bauzeit
             WHERE   bauzeit BETWEEN x AND y
             AND     bewertung = 'OK' )
    AND     ID NOT IN (   SELECT   ID
               FROM   tab_durchlauf
               WHERE   ... )
    AND     ID NOT IN (   SELECT   ID
               FROM   tab_testmodul
               WHERE   ... )
    ausprobiert?
     
  10. kwakz

    kwakz Aktiver Benutzer

    Daran probier ich mich gerade ... in der Therorie müsste ich ja in jeder Tabelle mit der gleichen Abfrage (natürlich abgesehen von den ersten beiden Zeilen) die gleichen IDs herausbekommen ... aktuell ist dem aber nicht so. da werde ich wohl noch ein bisschen knobeln müssen
     
  11. ukulele

    ukulele Datenbank-Guru

    Raff ich nicht. Jede Unterabfrage muss eine Liste mit IDs liefern. Ob die ID in der Liste steht prüft die Abfrage selbst.

    Einzig zu beachten ist das bei einer Unterabfrage mit kein NULL Wert in der id Spalte stehen darf, das dürfte aber eh nicht der Fall sein.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden