# Bitte Hilfe für mySQL in einem Query



## Guest (11. Okt 2005)

Hallo, ich habe ein Performanceproblem mit folgendem Sachverhalt unter mySQL, wäre schön wenn mir jemand von euch helfen kann 

Ich habe folgende Tabellen:


```
Tabelle1 (ca. 700.000 Sätze)
---------
nr(long)
datum(date)

Tabelle2 (ca. 1.000 Sätze)
---------
nr2(long)
typ(date)
```

Nun möchte ich alle Sätze haben, bei denen folgende Eigenschaften gegeben sind:

(Tabelle1.nr = Tabelle2.nr2 und kein Tabelle1.datum > (heute-10 tage) und Tabelle2.typ = 1) und alle von Tabelle2, die keine Übereinstimmung mit Tabelle1.nr haben.

Mein Query sieht momentan wie folgt aus:


```
SELECT 
Tabelle2.nr2, 
Tabelle1.nr, 
max(Tabelle1.datum)as deadline
FROM 
Tabelle2 
LEFT JOIN 
Tabelle1 
ON 
Tabelle1.nr = Tabelle2.nr2 
GROUP BY 
Tabelle1.nr  
HAVING (
(deadline > (NOW() - INTERVAL 10 DAY)) = 0 
OR 
Tabelle2.nr2 IS NULL 
) AND 
Tabelle2.typ = 1 
ORDER BY 
Tabelle1.nr
```

Funktionert auch soweit ganz gut. Jedoch dauert die Abfrage trotz Index, optimize table auf recht guter Hardware ganze 15 Sekunden. 

Ich bin jetzt nicht so der SQL-Profi, dass ich da eine schnellere Methodik finden kann.

Hat von euch jemand eine leuchtende Idee? 

Danke!


----------



## KSG9|sebastian (12. Okt 2005)

sicher das es an der sql liegt ? führst du die anweisung in nem sql tool aus (query browser...) oder ausm code raus ?

zeig mal den code her, falls es welchen gibt


----------



## Gast (12. Okt 2005)

Ja, ich nutze das in einem Querybrowser.


----------



## Bleiglanz (12. Okt 2005)

worauf ist ein Index

doch hoffentlich einer auf 

Tabelle1.nr

und einer auf 

Tabelle2.nr2 


```
SELECT
Tabelle2.nr2,
Tabelle1.nr,
max(Tabelle1.datum)as deadline
FROM
Tabelle2
LEFT JOIN
Tabelle1
ON
Tabelle1.nr = Tabelle2.nr2
GROUP BY
Tabelle1.nr, Tabelle2.nr2 

-- hier müssen beide stehen!!!
-- oder oben in der SELECT Klausel eine weglassen
 
HAVING 
(
   (deadline > (NOW() - INTERVAL 10 DAY)) = 0 
   OR

-- jetzt wirds unsinnig: warum das IS NULL
-- bei einem LEFT JOIN
-- und wenn, dann gehört das ins WHERE!

   Tabelle2.nr2 IS NULL
) 
AND

-- das nächste ist auch unsinnig
-- im Having ist ja schon gruppiert!
-- auch das gehört ins WHERE

    Tabelle2.typ = 1
ORDER BY
Tabelle1.nr
```


----------



## Gast (12. Okt 2005)

Auf nr und nr2 etc. ist ein Index gesetzt.



> warum das IS NULL
> -- bei einem LEFT JOIN



Damit ich auch die Datensätze sehe, die in Tabelle1 keine Übereinstimmung zu nr2 haben. In das where kann das nicht, weil sich das auf das 

(deadline > (NOW() - INTERVAL 10 DAY)) = 0 
   OR 

bezieht und den Alias "deadline" kann ich in der where-Klausel ja nicht ansprechen.


----------



## Bleiglanz (12. Okt 2005)

> (Tabelle1.nr = Tabelle2.nr2 und kein Tabelle1.datum > (heute-10 tage) und Tabelle2.typ = 1) und alle von Tabelle2, die keine Übereinstimmung mit Tabelle1.nr haben.


was willst du eigentlich mit "alle von Tabelle2, die keine Übereinstimmung mit Tabelle1.nr haben", bei denen kommt doch eh nur NULL,NULL heraus??

auf jeden fall kannst du

Tabelle2.nr2 und Tabelle2.typ

nicht in der HAVING-Klausel benutzen, weil sie nicht in deiner GROUP-BY vorkommen!!!

eher sowas

```
SELECT Tabelle2.nr2, max(Tabelle1.datum) AS deadline

FROM Tabelle2 LEFT JOIN Tabelle1                                                 

ON (Tabelle1.nr = Tabelle2.nr2)

WHERE
    Tabelle2.typ = 1

GROUP BY 
    Tabelle2.nr2

HAVING
    (deadline IS NULL) OR (deadline > (NOW() - INTERVAL 10 DAY)) 

ORDER BY
    Tabelle2.nr2
```
davon abgesehen ist die Performanz eh noch gut

700.000 x 1000 (zusammengeschlagen durch die Indizes)

kann nicht superfix gehen...


----------



## KSG9|sebastian (12. Okt 2005)

Hast du mal Sub-Selects versucht, die sind meistens performanter


----------



## Gast (12. Okt 2005)

"alle von Tabelle2, die keine Übereinstimmung mit Tabelle1.nr haben", 

Nein, dann kommt nr, null raus.

Es geht darum, dass Tabelle2 eine Artikeltabelle ist und Tabelle1 alle Verkäufe speichert.

So kann ich sehen welche Artikel noch nie bzw. in den letzten 10 Tagen nicht verkauft wurden um am Preis oder so zu drehen.


----------

