LIKE-Mustervergleichsbedingung erwartet, Zeichentypen sowohl als linke als auch als rechte Operanden zu sehen. Wenn es auf eine ZAHL trifft, wandelt es sie implizit in char um. Ihre Abfrage 1 wird im Grunde stillschweigend wie folgt umgeschrieben:
SELECT a1.*
FROM people a1
WHERE TO_CHAR(a1.id) LIKE '119%'
AND ROWNUM < 5
Das passiert in Ihrem Fall, und das ist aus zwei Gründen schlecht:
- Die Konvertierung wird für jede Zeile ausgeführt, was langsam ist;
- Aufgrund einer Funktion (obwohl implizit) in einem WHERE-Prädikat ist Oracle nicht in der Lage, den Index auf
A1.ID
zu verwenden Spalte.
Um dies zu umgehen, müssen Sie einen der folgenden Schritte ausführen:
-
Erstellen Sie einen funktionsbasierten Index auf
A1.ID
Spalte:CREATE INDEX people_idx5 ON people (TO_CHAR(id));
-
Wenn Sie Datensätze mit den ersten 3 Zeichen der ID-Spalte abgleichen müssen, erstellen Sie eine weitere Spalte vom Typ NUMBER, die nur diese 3 Zeichen enthält, und verwenden Sie ein einfaches = Operator drauf.
-
Erstellen Sie eine separate Spalte
ID_CHAR
vom TypVARCHAR2
und füllen Sie es mitTO_CHAR(id)
. Indexieren Sie es und verwenden Sie stattID
in IhremWHERE
Zustand.Wenn Sie sich entscheiden, eine zusätzliche Spalte basierend auf einer vorhandenen ID-Spalte zu erstellen, müssen Sie diese beiden natürlich synchron halten. Sie können dies im Batch als einzelnes UPDATE oder in einem ON-UPDATE-Trigger tun oder diese Spalte dem entsprechenden hinzufügen INSERT- und UPDATE-Anweisungen in Ihrem Code.