warunek dopasowania wzorca LIKE oczekuje, że typy znaków będą widziane zarówno jako operandy lewostronne, jak i prawostronne. Gdy napotka NUMBER, niejawnie konwertuje go na znak. Twoje zapytanie 1 jest w zasadzie po cichu przepisane na to:
SELECT a1.*
FROM people a1
WHERE TO_CHAR(a1.id) LIKE '119%'
AND ROWNUM < 5
Tak dzieje się w twoim przypadku, a to jest złe z dwóch powodów:
- Konwersja jest wykonywana dla każdego wiersza, co jest powolne;
- Ze względu na funkcję (choć niejawną) w predykacie WHERE, Oracle nie może użyć indeksu
A1.ID
kolumna.
Aby to obejść, musisz wykonać jedną z następujących czynności:
-
Utwórz indeks oparty na funkcjach na
A1.ID
kolumna:CREATE INDEX people_idx5 ON people (TO_CHAR(id));
-
Jeśli chcesz dopasować rekordy w pierwszych 3 znakach kolumny ID, utwórz kolejną kolumnę typu NUMBER zawierającą tylko te 3 znaki i użyj zwykłego = operator na nim.
-
Utwórz oddzielny kolumna
ID_CHAR
typuVARCHAR2
i wypełnij goTO_CHAR(id)
. Indeksuj go i używaj zamiastID
w swoimWHERE
stan.Oczywiście, jeśli zdecydujesz się utworzyć dodatkową kolumnę w oparciu o istniejącą kolumnę ID, musisz zachować te 2 zsynchronizowane. Możesz to zrobić wsadowo jako pojedynczą aktualizację lub w wyzwalaczu ON-UPDATE lub dodać tę kolumnę do odpowiedniej Instrukcje INSERT i UPDATE w kodzie.