SQL Abfrage "not in" zu langsam

  • Hey Leute,

    ich möchte in einem XT-Commerce Shop kurz abfragen wie viel Leute
    es gibt die Registriert sind aber noch nie bestellt haben.

    Ich benutze folgendes SQL-Statement dafür:

    SQL
    SELECT count(customers_id) 
    FROM `customers` 
    WHERE customers_id NOT 
    IN (
    SELECT customers_id
    FROM orders
    )


    Leider bekomme ich nie ein Ergebnis weil die Abfrage zu lange dauert hängt sich wohl immer der SQL Server auf (auch Lokal).

    In der Tabelle customers befinden sich: 61,421 Datensätze
    und in der Tabelle orders sind es: 55,793 Datensätze.


    Hat jemand ne Idee wie ich die Abfrage performanter gestalten kann?

    Vielen Dank

  • Ich würde der Tabelle customers ein feld `bestellt` o.ä. hinzufügen. default null, bei einer Bestellung auf 1 setzen.
    Dann sparst du dir die unterabfrage und ein boolean-feld mehr in der customers-tabelle macht den Braten nicht fett.

    Ist ein schönes Beispiel dafür, dass man manchmal in Sachen Normalisierung ein bißchen zurückstecken sollte zugunsten der Performance.

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

  • Hey,

    das kam oben vielleicht ein bischen falsch rüber ich möchte das nur
    1mal aktuell ausführen da ich die Info benötige.

    Ich benötige die Info also auch rückwirkend für die Leute die aktuell
    schon bestellt haben.

  • Wenn du es wirklich nur ein einziges Mal ausführen willst würde ich es einfach in zwei Abfragen aufteilen.
    Eine um die IDs auszulesen die schonmal etwas bestellt haben.
    Die Zweite um aus `customers` alle auszulesen, die nicht in der Menge enthalten sind.
    Unterabfragen sind immer langsam und sofern irgend möglich zu vermeiden.

    Wenn du es nicht nur einmal brauchst, sondern gelegentlich mal (bist du wirklich sicher dass du das nie wieder brauchst?) würde ich meine vorgeschlagene Lösung nehmen. Zum Aktualisieren der Customerstabelle brauchst du ja nur eben ein Script, das dir die IDs (distinct) ausliest die schon etwas gekauft haben und für diese IDs dann die neue Spalte `gekauft`auf 1 setzen.

    "Programming today is a race between software engineers
    striving to build bigger and better idiot-proof programs,
    and the universe trying to build bigger and better idiots.
    So far, the universe is winning."
    Rick Cook

    Einmal editiert, zuletzt von SinnlosS (21. August 2009 um 00:46)