2008-09-25 13 views
11

Este¿Tiene algún impacto en el rendimiento de Oracle al usar LIKE 'cadena' vs = 'cadena'?

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; 

es más lento que este

SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; 

pero ¿qué pasa esto?

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value'; 

Mi prueba indica el segundo y tercer ejemplos son exactamente los mismos. Si eso es cierto, mi pregunta es, ¿por qué usar "="?

+0

¿Qué prueba hiciste? –

+0

1 - Se ejecutó una instrucción en una tabla grande utilizando ambos métodos muchas veces, teniendo en cuenta el tiempo de ejecución 2 - Miró el plan de explicación – JosephStyons

Respuesta

17

Hay una clara diferencia cuando utiliza variables de vinculación, que debe utilizar en Oracle para cualquier otra cosa que no sea el almacenamiento de datos u otras operaciones de datos masivos.

Tomemos el caso de:

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE :b1 

Oracle no puede saber que el valor de: b1 es '% some_value%', o 'some_value' etc., hasta que el tiempo de ejecución, por lo que hará una estimación de la cardinalidad del resultado basado en heurística y proponer un plan apropiado que puede o no ser adecuado para varios valores de: b, como '% A', '%', 'A', etc.

Similar los problemas pueden aplicarse con un predicado de igualdad, pero el rango de cardinalidades que pueden resultar es mucho más fácil de estimar en base a las estadísticas de columna o la presencia de una restricción única, por ejemplo le.

Por lo tanto, personalmente no comenzaría a utilizar LIKE como un reemplazo para =. El optimizador es bastante fácil de engañar a veces.

+0

¡Buena respuesta! Parecía una tontería cuando leía la pregunta, pero no podía decir exactamente por qué. Esta es la respuesta correcta. –

5

Eche un vistazo a EXPLAIN PLAN para ambos. Generan el mismo plan de ejecución, por lo que para la base de datos, son lo mismo.

Utilizaría = para probar la igualdad, no la similitud. Si también está controlando el valor de comparación, entonces no hace mucha diferencia. Si un usuario lo envía, entonces 'apple' y 'apple%' le darán resultados muy diferentes.

+0

Para tablas muy grandes, puede haber una diferencia de rendimiento notable entre la prueba LIKE e = incluso el plan es idéntico. Pero es mejor probar. –

+0

Sí, si usa la variable de vinculación, como debería, el optimizador realmente no sabe qué le va a pasar. Por lo tanto, no necesariamente se puede optimizar para tener un comodín en un solo lado. (Por supuesto, Oracle puede haber trabajado alrededor de esa característica). –

1

¿Lo has probado? Las pruebas son la única forma segura de saberlo.

Como nota aparte, ninguna de estas afirmaciones devolverá las mismas filas. Pruebe:

insert into some_table (some_field) values ('some_value'); 
insert into some_table (some_fieled) values ('1some_value2'); 
insert into some_table (some_field) values ('some1value'); 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value'; 

En términos de claridad y para evitar errores sutiles, lo mejor es no usar nunca COMO a menos que necesite su funcionalidad comodín. (Obviamente, cuando se realizan consultas ad-hoc, es probable que esté bien.)

+0

¿cómo se ve la diferencia en los resultados? No tengo acceso a un servidor de espacio aislado para probar tu ejemplo. – Luke

+0

'LIKE '% some_value%'' devuelve los tres registros, '= 'some_value'' devuelve solo el segundo registro,' LIKE' some_value'' devuelve el primer y el tercer registro. –

1

LIKE '% WHATEVER%' tendrá que hacer un escaneo completo del índice.

Si no hay porcentaje, entonces actúa como un igual.

Si el% está en un extremo, entonces el índice puede ser una exploración de rango.

No estoy seguro de cómo el optimizador maneja los campos enlazados.

3

Si eso es cierto, mi pregunta es, ¿por ha consumido alguna vez "="?

Una mejor pregunta: ¿Si eso es cierto, ¿por qué utilizar "Me gusta" para comprobar la igualdad? Puedes guardar presionando la tecla Mayús y todos los que leen el guión se confunden.

1

like es formalmente lo mismo si no tiene caracteres como $% etc. por lo que no es una gran sorpresa encontrar que tiene el mismo costo.

Encuentro que la respuesta de David Aldridge es interesante ya que su aplicación debería usar variables de vinculación. Con like '%foobar' no puede hacer uso de ordenar en el índice. Si la consulta está precompilada, dará lugar a más Escaneos completos de índice o tabla.

Por otra parte, creo que es peligroso ya que puede conducir a inyecciones SQL y bichos extraños (por ejemplo, si hay un usuario llamado John que un hacker puede crear un usuario llamado 'joh$' y tratar de conectarse)

qué ¿tomar el riesgo? '=' es más claro y no tiene ninguno de esos problemas.

Cuestiones relacionadas