2009-04-30 8 views
0

Wie kann ich diese Abfrage optimieren? Es scheint, dass es einen viel einfacheren Weg geben sollte, dies zu tun. Das Ziel ist, dass es immer noch in eine Löschanweisung umgewandelt werden kann.Wie kann ich diese Abfrage optimieren?

SELECT * FROM team 
WHERE team_id IN (
        SELECT team_id 
        FROM (
         SELECT team.team_id, (
               SELECT COUNT(*) 
               FROM signup 
               WHERE signup.team_id = team.team_id 
              ) AS members 
         FROM team, schedule, event 
         WHERE team.schedule_id = schedule.schedule_id 
         AND schedule.event_id = event.event_id 
         AND event.event_id =183) AS t 
        WHERE members = 0 
       ) 
+0

Können Sie etwas mehr über die Daten und was die Abfrage tun/zurückgeben? –

+1

Und wie wäre es, wenn Sie diesen Code etwas besser formatieren ... –

+1

Ich habe den Code für Sie formatiert. Es ist sehr hilfreich, alle SQL-Daten in Großbuchstaben zu schreiben und Ihre Tabellen, Spalten und Aliase klein zu schreiben. Dann ist es auch eine gute Idee, den Code einzurücken. Auf diese Weise können Sie tatsächlich sehen, was die Abfrage macht. – markus

Antwort

3

Ein kurzer Blick auf diese Abfrage gibt mir dies:

select 
    t.* 
from 
    team t 
    inner join schedule s on t.schedule_id = s.schedule_id 
    inner join event e on s.event_id = e.event_id 
    left outer join signup sp on t.team_id = sp.team_id 
where 
    e.event_id = 183 
    and sp.team_id is null 

Es sah aus wie Sie versuchen, alle Teams zu finden, die in einem Fall sind, aber nicht in der Registrierung Tabelle. Ist das genau?

Auch wollte ich zur Kenntnis nehmen, dass es schneller wird, Joins zu tun, dann eine Reihe von Unterabfragen, vor allem, wenn die Unterabfragen von jeder Zeile abhängen (in Ihrem Fall, sie tun).

Cheers,
Eric

+0

Danke, das ist genau das, was ich wollte. Ich arbeite immer noch daran, verschiedene Arten von Joins gut zu nutzen. (Ich sollte beachten, dass auf der zweiten inneren Join in Sie Abfrage war es eigentlich.event_id = e.event_id, nicht schedule_id) – Craig

+0

behoben, und froh, dass es geholfen hat! – Eric

+1

Jetzt, da Sie besser SQL haben, stellen Sie sicher, dass Sie den Abfrageplan für die Abfrage überprüfen. Wenn Sie die Optimierung abschließen möchten, sollten Sie sicherstellen, dass es auch schnell geht. Wenn die Tabellen groß sind (oder irgendwann groß werden) und Sie nicht über die richtigen Indizes verfügen, wird die Abfrage langsam ausgeführt. Wenn Sie Indizes hinzufügen und Ihre Schreibvorgänge langsam werden, geben Sie eine weitere Frage ein und wir werden Ihnen antworten. – yetanotherdave

0

auf Erics Abfrage in diesem Thread kommentierte, würde ich (aus meiner mssqlserver Hintergrund) empfehlen stattdessen eine existenzielle Prüfung zu verwenden. Wenn Sie dies tun (1), wird Ihre Absicht klarer und (2) gibt dem Optimierer die Möglichkeit, die Suche nach einer passenden team_id zu stoppen, nachdem die erste gefunden wurde (da> = 1 übereinstimmende Zeile bewirkt, dass die Existenzprüfung falsch ist). Zum Beispiel

wählen t. * von Team t Exklusionsverknüpfung Zeitplan s auf t.schedule_id = s.schedule_id Exklusionsverknüpfung Ereignis e auf s.event_id = e.event_id wo e.event_id = 183 und nicht vorhanden (wählen Sie * aus der Anmeldung, wo team_id = t.team_id)

Aber vielleicht gibt es mysql spezifische perf Anliegen.