condição de correspondência de padrão LIKE espera ver os tipos de caracteres como operandos do lado esquerdo e do lado direito. Quando encontra um NUMBER, converte-o implicitamente em char. Sua consulta 1 é basicamente reescrita silenciosamente para isso:
SELECT a1.*
FROM people a1
WHERE TO_CHAR(a1.id) LIKE '119%'
AND ROWNUM < 5
Isso acontece no seu caso, e isso é ruim por 2 motivos:
- A conversão é executada para cada linha, o que é lento;
- Devido a uma função (embora implícita) em um predicado WHERE, o Oracle não pode usar o índice em
A1.ID
coluna.
Para contornar isso, você precisa fazer um dos seguintes:
-
Crie um índice baseado em função emA1.ID
coluna:
CREATE INDEX people_idx5 ON people (TO_CHAR(id));
-
Se você precisar corresponder registros nos primeiros 3 caracteres da coluna ID, crie outra coluna do tipo NUMBER contendo apenas esses 3 caracteres e use um = simples operador nele.
-
Crie um separado colunaID_CHAR
do tipoVARCHAR2
e preencha comTO_CHAR(id)
. Indexe-o e use em vez deID
em seuWHERE
doença.
É claro que se você optar por criar uma coluna adicional com base na coluna de ID existente, precisará manter essas 2 sincronizadas. Você pode fazer isso em lote como um único UPDATE ou em um gatilho ON-UPDATE ou adicionar essa coluna ao apropriado Instruções INSERT e UPDATE em seu código.