0Pricing
Coding Interview Prep · Lektion

Nach berechneten Werten filtern

Warum Funktionen auf Spalten die Indexnutzung verhindern und wie Interviewer dieses Thema prüfen

Nach berechneten Werten filtern ist eine kostenlose Coding Interview Prep-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Coding Interview Prep-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.

Warum diese Frage Erfahrungsstufen unterscheidet

Die Frage klingt harmlos: Diese Abfrage ist korrekt, aber langsam – warum? Oft liegt die Antwort darin, dass die WHERE-Klausel eine indizierte Spalte in eine Funktion einschließt. Dadurch wird das Prädikat nicht sargierbar: Der Optimierer kann den Index nicht mehr verwenden und muss jede Zeile durchsuchen.

Diese Lektion erklärt die Sargierbarkeit, zeigt die von Interviewern erwarteten Umformulierungen und behandelt, wo ein berechneter Filter tatsächlich hingehört.

Sargierbar auf den Punkt gebracht

Sargierbar (Search ARGument ABLE) bedeutet, dass ein Prädikat einen Index verwenden kann, um direkt zu passenden Zeilen zu gelangen. Als Faustregel gilt: Die indizierte Spalte muss auf einer Seite des Vergleichs unverändert stehen und darf nicht in einer Funktion oder einem Ausdruck verborgen sein.

  • Sargierbar: col = 5, col > 100, col LIKE 'abc%'
  • Nicht sargierbar: FUNC(col) = 5, col + 1 > 100

Das Anti-Pattern „Funktion auf der Spalte“

Hier geht es um Bestellungen aus dem Jahr 2024. Wenn die Spalte in YEAR() eingeschlossen wird, muss die Datenbank für jede einzelne Zeile zunächst das Jahr berechnen, bevor sie den Vergleich durchführen kann. Dadurch ist der Index auf order_date nutzlos.

Die Abfrage liefert zwar das richtige Ergebnis, durchsucht aber die gesamte Tabelle. Bei einer großen Tabelle bedeutet das den Unterschied zwischen Millisekunden und Minuten.

-- non-sargable: function on the indexed column
SELECT *
FROM orders
WHERE YEAR(order_date) = 2024;

Als Bereichsbedingung umschreiben

Die Lösung besteht darin, order_date unverändert zu lassen und die Bedingung als halboffenen Bereich auszudrücken. Nun kann der Index auf order_date direkt zum Beginn des Jahres 2024 springen und bei 2025 anhalten.

Dasselbe Ergebnis, aber mit einem Indexbereichsscan statt eines vollständigen Scans. Diese Umformulierung in einen Bereich ist die am häufigsten geprüfte Lösung für Sargierbarkeit in Interviews.

-- sargable: column stays bare
SELECT *
FROM orders
WHERE order_date >= '2024-01-01'
  AND order_date <  '2025-01-01';

Arithmetik auf der Spalte

Dasselbe Problem tritt bei arithmetischen Ausdrücken auf. WHERE salary + bonus > 100000 oder WHERE price * 0.9 < 50 führen beide eine Berechnung mit der Spalte durch und verhindern die Verwendung des Index.

Verschieben Sie die Berechnung nach Möglichkeit auf die Seite der Konstanten: Schreiben Sie price * 0.9 < 50 als price < 50 / 0.9 um. Das Literal wird einmal berechnet, und price bleibt unverändert und damit für den Index nutzbar.

-- before: math on the column (non-sargable)
WHERE price * 0.9 < 50
-- after: math on the constant (sargable)
WHERE price < 50 / 0.9

Die Variante für die Suche ohne Beachtung der Groß-/Kleinschreibung

WHERE LOWER(email) = 'a@b.com' ist gegenüber einem einfachen Index auf email nicht sargierbar, weil zunächst die E-Mail-Adresse jeder Zeile in Kleinbuchstaben umgewandelt wird.

Für die Produktion gibt es zwei Lösungen: Speichern Sie eine normalisierte Kopie in Kleinbuchstaben und indizieren Sie diese, oder erstellen Sie einen Funktionsindex auf LOWER(email), sodass der Ausdruck selbst indiziert wird. Wenn Sie die Option eines Funktionsindex nennen, zeigen Sie Erfahrung mit realen Systemen.

-- functional index makes the expression sargable
CREATE INDEX idx_email_lower ON users (LOWER(email));
SELECT * FROM users WHERE LOWER(email) = 'a@b.com';

Wenn Sie tatsächlich eine Berechnung benötigen

Manchmal hängt der Filter tatsächlich von einem berechneten Wert ab, für den es keine Umformulierung in einen Bereich gibt, etwa bei einer Filterung nach einem Verhältnis. Sie können in WHERE trotzdem keinen Alias aus SELECT verwenden, da WHERE vor der SELECT-Liste ausgewertet wird.

Sie müssen den Ausdruck daher entweder in WHERE wiederholen oder die Abfrage in eine Unterabfrage bzw. einen CTE einschließen und die berechnete Spalte in der äußeren Abfrage filtern.

SELECT *
FROM (
  SELECT *, revenue / NULLIF(visits, 0) AS rev_per_visit
  FROM stats
) t
WHERE t.rev_per_visit > 2.5;

Aggregatfilter gehören in HAVING, nicht WHERE

Eine Berechnung, die ein Aggregat ist, kann überhaupt nicht in WHERE stehen, weil WHERE einzelne Zeilen filtert, bevor die Gruppierung stattfindet. WHERE SUM(amount) > 1000 führt zu einem Fehler.

Filter für Aggregate gehören in HAVING, das nach GROUP BY ausgeführt wird. Zu wissen, welche Klausel die Berechnung sieht, ist selbst eine häufige Frage zur Ausführungsreihenfolge.

SELECT customer_id, SUM(amount) AS total
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 1000;

So prüfen Interviewer dieses Thema

Interviewer zeigen eine langsame Abfrage mit einer Funktion auf einer Spalte und bitten Sie, sie schneller zu machen, ohne das Ergebnis zu ändern. Gehen Sie so vor:

  • Erkennen Sie die Funktion auf der Spalte als nicht sargierbar
  • Formulieren Sie die Bedingung so um, dass die Spalte unverändert bleibt (Bereich oder Berechnung auf der Konstantenseite)
  • Wenn keine Umformulierung möglich ist, schlagen Sie einen Funktionsindex oder eine gespeicherte berechnete Spalte vor

Wenn Sie EXPLAIN erwähnen, um zu bestätigen, dass sich der Ausführungsplan von einem sequenziellen Scan zu einem Indexscan geändert hat, runden Sie die Antwort ab.

Bewusstsein für Zielkonflikte

Bleiben Sie ausgewogen: Indizes und Funktionsindizes beschleunigen Lesevorgänge, verlangsamen aber Schreibvorgänge und benötigen Speicherplatz. Bei einer sehr kleinen Tabelle ist ein vollständiger Scan in Ordnung, und das Hinzufügen eines Index wäre vergebliche Mühe.

Die Antwort auf Senior-Niveau ist abhängig vom Kontext: Wenn diese Spalte groß ist und häufig auf diese Weise gefiltert wird, machen Sie das Prädikat sargierbar oder fügen Sie einen Funktionsindex hinzu; andernfalls lassen Sie es unverändert. Im Interview ist der Kontext wichtiger als starre Regeln.

Funktionale Indizes machen eine Berechnung sargable

Manchmal müssen Sie tatsächlich nach einem transformierten Wert filtern – etwa bei einem Vergleich ohne Beachtung der Groß- und Kleinschreibung. Anstatt auf Indizes zu verzichten, erstellen Sie einen Ausdrucksindex (funktionalen Index) für genau den Ausdruck, nach dem Sie filtern.

  • Der Optimizer kann den Index dann verwenden, obwohl eine Funktion die Spalte umschließt.
  • Der Indexausdruck muss exakt mit dem Ausdruck im Prädikat übereinstimmen.
-- index the expression you filter on
CREATE INDEX idx_users_lower_email ON users (lower(email));

-- now this predicate stays sargable
SELECT * FROM users WHERE lower(email) = 'amy@example.com';

Schnelle Überprüfung

Bestimmen Sie, welches Prädikat der Optimierer mit einem Index ausführen kann.

Zusammenfassung

Die wichtigsten Punkte:

  • Ein Prädikat ist sargierbar, wenn die indizierte Spalte unverändert erscheint und nicht in einer Funktion oder arithmetischen Berechnung steckt
  • Schreiben Sie YEAR(col) = 2024 als halboffenen Bereich um und verschieben Sie Berechnungen auf die Seite der Konstanten
  • Für unvermeidbare Ausdrücke verwenden Sie einen Funktionsindex oder eine gespeicherte berechnete Spalte
  • Ein Alias aus SELECT kann nicht in WHERE verwendet werden; Aggregate gehören in HAVING

Die klassische Frage betrifft eine langsame Abfrage; die klassische Lösung besteht darin, die Spalte unverändert zu lassen.

Häufig gestellte Fragen

Ist die Lektion „Nach berechneten Werten filtern“ kostenlos?

Ja — der vollständige Text von „Nach berechneten Werten filtern“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Coding Interview Prep-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Coding Interview Prep-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Nach berechneten Werten filtern“?

Warum Funktionen auf Spalten die Indexnutzung verhindern und wie Interviewer dieses Thema prüfen Du übst Coding Interview Prep mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Coding Interview Prep zu starten?

Keine Vorkenntnisse erforderlich. Coding Interview Prep auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Nach berechneten Werten filtern“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Coding Interview Prep-Lektion Code schreiben und ausführen?

Ja. Jede Coding Interview Prep-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. AND/OR-Rangfolge und Klammerung
  2. BETWEEN, IN und inklusive Grenzen
  3. LIKE, Platzhalter und Escaping
  4. Nach berechneten Werten filtern
← Zurück zu Coding Interview Prep