SOM mönstermatchande skick förväntar sig att se teckentyper som operander på både vänster och höger sida. När den stöter på ett NUMMER konverterar den implicit det till char. Din fråga 1 är i princip tyst omskriven till detta:
SELECT a1.*
FROM people a1
WHERE TO_CHAR(a1.id) LIKE '119%'
AND ROWNUM < 5
Det händer i ditt fall, och det är dåligt av två anledningar:
- Konverteringen utförs för varje rad, vilket är långsamt;
- På grund av en funktion (men implicit) i ett WHERE-predikat kan Oracle inte använda indexet på
A1.ID
kolumn.
För att komma runt det måste du göra något av följande:
-
Skapa ett funktionsbaserat index på
A1.ID
kolumn:CREATE INDEX people_idx5 ON people (TO_CHAR(id));
-
Om du behöver matcha poster på de första tre tecknen i ID-kolumnen, skapa en annan kolumn av typen NUMBER som bara innehåller dessa tre tecken och använd en vanlig = operatör på den.
-
Skapa en separat kolumn
ID_CHAR
av typenVARCHAR2
och fyll den medTO_CHAR(id)
. Indexera det och använd istället förID
i dinWHERE
skick.Om du väljer att skapa ytterligare en kolumn baserad på befintlig ID-kolumn måste du naturligtvis hålla dessa 2 synkroniserade. Du kan göra det i batch som en enda UPPDATERING, eller i en ON-UPDATE-utlösare, eller lägga till den kolumnen i lämplig INSERT och UPDATE-satser i din kod.