LIKE condition de correspondance de modèle s'attend à voir les types de caractères comme des opérandes à gauche et à droite. Lorsqu'il rencontre un NUMBER, il le convertit implicitement en char. Votre requête 1 est essentiellement réécrite silencieusement :
SELECT a1.*
FROM people a1
WHERE TO_CHAR(a1.id) LIKE '119%'
AND ROWNUM < 5
Cela se produit dans votre cas, et c'est mauvais pour 2 raisons :
- La conversion est exécutée pour chaque ligne, ce qui est lent ;
- En raison d'une fonction (bien qu'implicite) dans un prédicat WHERE, Oracle est incapable d'utiliser l'index sur
A1.ID
colonne.
Pour contourner ce problème, vous devez effectuer l'une des actions suivantes :
-
Créer un index basé sur les fonctions sur
A1.ID
colonne :CREATE INDEX people_idx5 ON people (TO_CHAR(id));
-
Si vous avez besoin de faire correspondre des enregistrements sur les 3 premiers caractères de la colonne ID, créez une autre colonne de type NUMBER contenant uniquement ces 3 caractères et utilisez un simple = opérateur dessus.
-
Créer un distinct colonne
ID_CHAR
de typeVARCHAR2
et remplissez-le avecTO_CHAR(id)
. Indexez-le et utilisez-le à la place deID
dans votreWHERE
état.Bien sûr, si vous choisissez de créer une colonne supplémentaire basée sur la colonne d'ID existante, vous devez les synchroniser. Vous pouvez le faire par lots en tant que mise à jour unique, ou dans un déclencheur ON-UPDATE, ou ajouter cette colonne à la colonne appropriée. Instructions INSERT et UPDATE dans votre code.