Einfache Frage. Fragen Sie sich, ob eine lange IN-Klausel ein Code-Geruch ist? Ich weiß nicht, wie ich das rechtfertigen soll. Ich kann nicht sagen, warum es anders riecht als das, was ich glaube.
%Vor%Wie implementiert eine Datenbank normalerweise eine solche Suche? Ist eine temporäre Tabelle erstellt und mit ihr verbunden? Oder wird es einfach zu einer Reihe von logischen ODERs erweitert?
Es fühlt sich an, als hätte es eine Verbindung sein sollen ...
Ich sage nicht, dass alle IN-Klauseln schlecht sind. Manchmal kann man nicht anders. Aber es gibt einige Fälle (vor allem, je länger sie bekommen), wo die Elemente, mit denen Sie übereinstimmen, tatsächlich von irgendwo herkommen. Und sollte das nicht stattdessen geschehen?
Lohnt es sich, (über die Anwendungsebene) eine temporäre Tabelle zu erstellen, die alle Elemente enthält, nach denen Sie suchen möchten, und dann einen echten Join dagegen macht?
%Vor% Ich denke, es ist ein Code-Geruch. Zum einen haben Datenbanken Grenzen in Bezug auf die Anzahl der erlaubten Elemente in einer IN
-Klausel, und wenn Ihr SQL dynamisch generiert wird, können Sie schließlich gegen diese Grenzen stoßen.
Wenn die Liste langsam wird, würde ich eine gespeicherte Prozedur mit einer temporären Tabelle verwenden, um Fehler zu vermeiden.
Ich bezweifle jedoch, dass die Leistung ein großes Problem ist, obwohl IN
-Klauseln sehr schnell sind, da sie im Gegensatz zu NOT IN
-Klauseln sehr kurz sein können.
Ist es sinnvoll, über die Anwendungsebene eine temporäre Tabelle zu erstellen?
Das Problem mit IN
ist, dass es keinen Index verwendet und der Vergleich (Worst Case: x14 hier) wird für jede Zeile in Ihrer Quelltabelle wiederholt.
Das Erstellen einer temporären Tabelle ist eine gute Idee, wenn Sie den Join-Feldern einen Index hinzufügen.
Auf diese Weise kann die Abfrage den Wert direkt suchen, wobei ein BTree-Index verwendet wird, der nur 3 oder 4 Vergleiche benötigt. Worst case log2 (14) = 3.etwas
Was viel schneller ist.
Wenn Sie schlau sind, können Sie sogar hash-index
verwenden. In diesem Fall muss die Datenbank nur einen Vergleich durchführen, was Ihre Abfrage im Vergleich zum btree-Index um das Dreifache beschleunigt.
Tipps zum Verwenden einer temporären Tabelle
Stellen Sie sicher, dass Sie eine Speichertabelle verwenden
Verwenden Sie hash index
als Primärschlüssel.
Probieren Sie die Inserts in einer Anweisung aus.
Die semi-konstante Zeit, die Sie für das Erstellen der Temp-Tabelle aufwenden, wird durch die Beschleunigung aufgrund der O (1) -Lookup-Zeit, die den Hash-Index verwendet, in den Schatten gestellt.
Ich weiß nicht, dass es genau ein Code-Geruch ist. Manchmal haben Sie nur eine lange Liste von Dingen in
, in denen Ihre Bedingung existieren könnte.
Wie mache ich eine temporäre Tabelle (oder sogar eine Nachschlagetabelle) mit den Elementen und verbinde mich dagegen (oder mache sogar eine where [column] in (select [lookup] from [lookuptable])
ist eine meiner bevorzugten Methoden IFF * a) Es gibt eine große Anzahl von Werten, die b) wird sich selten ändern, wenn überhaupt.
*: "Wenn und nur wenn"
Sie können auch eine Unterabfrage mit IN verwenden, wie in hier beschrieben das Handbuch .
%Vor% Ich halte es auch für einen "Geruch". Eine IN
-Klausel kann für einen zufälligen Beobachter einer Menge, Liste, Tasche, Tabelle usw. ähneln, ist aber nicht.
Gemäß den SQL-Standards ist Ihre IN
-Klausel lediglich syntaktischer Zucker für
Ich würde erwarten, dass ein typischer Parser eine IN
-Klausel genau auf diese Weise erweitert; Ich weiß, SQL Server tut, weil die netten, sauberen IN
-Klauseln, die ich zum Erstellen bestimmter CHECK
-Restriktionen verwende, zu einer unschönen Menge von OR
-Klauseln werden, wenn ich die Definition der Einschränkung in der INFORMATION_SCHEMA untersuche. YMMV: Wenn Sie über die Leistung besorgt sind, testen.
Es gibt eine Design-Faustregel, die besagt, dass, wenn die Menge der Werte klein und stabil ist, eine IN
-Klausel verwendet wird, andernfalls eine Tabelle. Ob 14 von 52 "klein" ist, ist subjektiv. Ob eine kleine Tabelle am besten indiziert wird, hängt möglicherweise davon ab, wie sie mit anderen Tabellen verknüpft wird: diese SO-Frage kann eine nützliche Referenz sein .
Tags und Links sql mysql database performance