mixmastertobsi: MySQL Subquery sehr langsam

Hallo,

ich habe eine MySQL abfrage, die sehr langsam ist. Wenn ich die Abfragen "einzeln" nacheinander Abfrage, ist es wesentlich schneller. An was liegt das?

LANGSAM

SELECT 
if(ai14.value IS NOT NULL, (SELECT value FROM auftrag_info as ai14_2 WHERE ai14_2.value=auftrag_ship.id AND ai14_2.auftragnr!=auftrag_ship.auftragnr), NULL) as result
FROM auftrag_ship 
JOIN auftrag_ship_fortras ON auftrag_ship_fortras.auftrag_ship_id=auftrag_ship.id
LEFT JOIN auftrag_info as ai14 on ai14.auftragnr=auftrag_ship.auftragnr AND ai14.value=auftrag_ship.id WHERE auftrag_ship.auftragnr='1'

schnell

SELECT ai14.value as id, auftrag_ship.auftragnr
FROM auftrag_ship 
JOIN auftrag_ship_fortras ON auftrag_ship_fortras.auftrag_ship_id=auftrag_ship.id
LEFT JOIN auftrag_info as ai14 on ai14.auftragnr=auftrag_ship.auftragnr AND ai14.value=auftrag_ship.id WHERE auftrag_ship.auftragnr='1'

=> nächte Abfrage, wenn nicht NULL

SELECT value as result FROM auftrag_info WHERE auftrag_info.value='$id' AND ai14_2.auftragnr!='$auftragnr'
  1. Tach!

    Wenn ich die Abfragen "einzeln" nacheinander Abfrage, ist es wesentlich schneller. An was liegt das?

    Um der Beantwortung der Frage näher zu kommen gibt es den Statementzusatz EXPLAIN, um Information zum Execution Plan zu bekommen.

    dedlfix.

  2. hast du mal geprüft ob die gejointe tabelle bei der ersten query viel größer ist als die der zweiten?

  3. Hallo mixmastertobsi,

    warum deine Query so langsam wird, kann ich so auch nicht sagen.

    Aber was willst Du eigentlich fachlich?

    Ich erkenne die Tabelle auftrag_ship mit den Spalten id und auftragnr.
    Dann auftrag_ship_fortras mit auftrag_ship_id, die ohne erkennbaren Zweck gejoined wird.
    Dann auftrag_info mit auftragnr und value (wobei value eine auftrag_ship ID ist), die du mit LEFT JOIN hinzufügst, aber eigentlich auch ohne erkennbaren Zweck.

    Du filterst auf auftragnr='1' und bekommst auf diese Weise eine ID.

    Und dann guckst Du, ob die auftrag_info zu dieser ID noch eine andere Auftragnr enthält.

    Das ist in der ersten Query schon deswegen riskant, weil du ja offenbar mehr als eine Auftragnr zu einer ID erwartest. Und wo es eine mehr geben kann, könnten es auch zwei mehr sein, und dann funktioniert dieser Inline-Select nicht mehr.

    Was aber scheinbar nicht der Fall ist, ist eine Mehrdeutigkeit auftragnr -> id, d.h. mehrere IDs zu einer Auftragsnummer gibt es nicht. Sonst würde deine Abfrage komplett aus dem Ruder laufen.

    Reicht nicht folgendes? Damit bekommst Du heraus, ob es eine weitere Auftragsnummer zur gleichen ID gibt. Ein Index auf auftrag_info.value wäre natürlich hilfreich für die Performance.

    select i2.value as result, i2.auftragnr as andereNr
    from auftrag_info i1 join auftrag_info_i2 on i1.value = i2.value
    where i1.auftragnr = '$auftragnr' and i2.auftragnr != '$auftragnr'
    

    Rolf

    --
    Dosen sind silbern