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.IDcoluna.
Para contornar isso, você precisa fazer um dos seguintes:
-
Crie um índice baseado em função emA1.IDcoluna:
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_CHARdo tipoVARCHAR2e preencha comTO_CHAR(id). Indexe-o e use em vez deIDem seuWHEREdoenç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.