2011-09-15 22 views
5

Estoy trabajando en una condición de unión entre 2 tablas donde una de las columnas para coincidir es una concatenación de valores. Necesito unir columnA desde tableA a los primeros 2 caracteres de columnB desde tableB.Rendimiento de la comparación de SQL utilizando subcadena vs como con el comodín

He desarrollado 2 declaraciones diferentes para manejar esto y he intentado analizar el rendimiento de cada método.

Método 1:

ON tB.columnB like tA.columnA || '%' 

Método 2:

ON substr(tB.columnB,1,2) = tA.columnA 

El plan de ejecución de la consulta tiene mucho menos pasos Método 1 en comparación con el método 2, sin embargo, parece que el método 2 se ejecuta mucho Más rápido. Además, el plan de ejecución muestra un índice recomendado para el Método 2 que podría mejorar su rendimiento.

Estoy ejecutando esto en un IBM iSeries, aunque estaría interesado en las respuestas en un sentido general para aprender más sobre la optimización de consultas SQL.

¿Tiene sentido que el Método 2 se ejecute más rápido?

Esta pregunta SO es similar, pero parece que nadie proporcionó ninguna respuesta concreta a la diferencia de rendimiento de estos enfoques: T-SQL speed comparison between LEFT() vs. LIKE operator.

PD: El diseño de la tabla que requiere este tipo de unión no es algo que pueda cambiarse en este momento. Me doy cuenta de que tener los campos separados que contienen diferentes tipos de datos sería preferible.

+0

¿INNER or OUTER JOIN? –

+0

Esto es para una unión interna. Se uniría al tipo de hacer una diferencia? – Swoop

+1

Bueno, probablemente sea un juego perdedor el adivinar qué está pasando en un optimizador de consultas. Pero sí, en este caso, si se trata de un UNIÓN INTERNA, el Método 1 requiere que se lea todo tA, mientras que el método 2 solo necesita leer tB. Dependiendo del número de filas, eso podría ser significativo y podría afectar el plan de ejecución. –

Respuesta

0

Encontré esta referencia en un libro rojo de IBM relacionado con el rendimiento de SQL. Parece que la función escalar SUBSTR puede ser manejada de manera optimizada por un iSeries.

Si busca el primer carácter y desea utilizar la SQE lugar del CQE, puede utilizar la subcadena función escalar en la señal izquierda del signo igual. Si tiene que buscar caracteres adicionales en la cadena, también puede usar la función escalar POSSTR. Por dividir el predicado LIKE en varias funciones escalares, puede afectar el optimizador de consultas para usar el SQE.

http://publib-b.boulder.ibm.com/abstracts/sg246654.html?Open

2

Sí, el método 2 sería más rápido. LIKE no es una función tan eficiente.

Para comparar el rendimiento de varias técnicas, intente utilizar Visual Explain. Lo encontrarás enterrado en System i Navigator. Debajo de su conexión del sistema, expanda las bases de datos, luego haga clic en su nombre RDB. En el panel inferior derecho, puede hacer clic en la opción Ejecutar un script SQL. Ingrese su declaración SELECT y elija la opción del menú para Explicación Visual o Ejecutar y Explicar. Explicación visual desglosará el plan de ejecución de su extracto y le mostrará el costo de cada parte según lo estimado en sus tablas con los índices disponibles.

+0

He estado usando Visual Explain para ayudar a optimizar mis consultas, pero todavía estoy tratando de aprender a sacar el máximo provecho de esta herramienta. ¿Conoces alguna documentación avanzada para ello? Mis búsquedas de Google hasta ahora solo han encontrado me gusta básicos, como cómo cargar Visual Explain. – Swoop

+0

LIKE puede ser bastante eficiente si el comodín está al final de la cadena de comparación y el motor entiende usar un índice disponible para la comparación. –

+0

@Larry ¿está diciendo en algunas circunstancias que el optimizador entendería un comodín al final para ser equivalente a LEFT()? ¿Puedes dar algún ejemplo en el que sería más eficiente? – WarrenT

2

que corrían el siguiente en el Asesor SQL en IBM Data Studio en una de las tablas en mi DB2 LUW 10.1 base de datos:

SELECT * 
FROM PDM.DB30 
WHERE DB30_SYSTEM_ID = 'XXX' 
    AND DB30_VERSION_ID = 'YYY' 
    AND SUBSTR(DB30_REL_TABLE_NM, 1, 4) = 'ZZZZ' 

y

SELECT * 
FROM PDM.DB30 
WHERE DB30_SYSTEM_ID = 'XXX' 
    AND DB30_VERSION_ID = 'YYY' 
    AND DB30_REL_TABLE_NM LIKE 'ZZZZ%' 

Ellos total de CPU tanto tenía la ruta exacta mismo acceso que utiliza el mismo índice, el mismo costo estimado IO y la misma cardinalidad estimado, siendo la única diferencia el estimado el costo para LIKE fue de 178,343.75, mientras que el SUBSTR fue de 197,518.48 (~ 10% de diferencia).

El costo total acumulado para ambos fue el mismo, por lo que esta diferencia es insignificante según el asesor.

0

En realidad se puede ejecutar con ejemplos reales en su base de datos.

LIKE es siempre mejor en mi carrera.

select count(*) from u_log where log_text like 'AUT%'; 
1 row(s) returned : 90ms taken 

select count(*) from u_log where substr(log_text,1,3)='AUT'; 
1 row(s) returned : 493ms taken 
Cuestiones relacionadas