¿Cómo hacer que una vista sindical se ejecute de manera más eficiente?


8

Tengo una tabla grande (decenas a cientos de millones de registros) que hemos dividido por razones de rendimiento en tablas activas y de archivo, utilizando un mapeo de campo directo y ejecutando un proceso de archivo todas las noches.

En varios lugares de nuestro código, necesitamos ejecutar consultas que combinen las tablas activas y de archivo, casi siempre filtradas por uno o más campos (que obviamente hemos puesto índices en ambas tablas). Por conveniencia, tendría sentido tener una vista como esta:

create view vMyTable_Combined as
select * from MyTable_Active
union all
select * from MyTable_Archive

Pero si ejecuto una consulta como

select * from vMyTable_Combined where IndexedField = @val

hará la unión en todo, desde Active y Store antes de filtrar @val, lo que va a matar el rendimiento.

¿Hay alguna forma inteligente de hacer que las dos subconsultas de la unión vean cada filtro @valantes de que creen la unión?

¿O tal vez hay algún otro enfoque que sugiera que logre lo que busco, es decir, una forma fácil y eficiente de obtener el conjunto de registros sindicales, filtrado por el campo indexado?

EDITAR: aquí está el plan de ejecución (y puedes ver los nombres reales de las tablas aquí):

plan de ejecución

Por extraño que parezca, la tabla activa está usando el índice correcto (¿más una búsqueda RID?) ¡Pero la tabla de archivo está escaneando la tabla!


Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Paul White 9

Respuestas:


8

Los comentarios sobre la pregunta muestran que el problema es que la base de datos de prueba que el OP estaba usando para desarrollar la consulta tenía características de datos radicalmente diferentes que la base de datos de producción. Tenía muchas menos filas y el campo que se usaba para filtrar no era lo suficientemente selectivo.

Cuando el número de valores distintos en una columna es demasiado pequeño, el índice puede no ser lo suficientemente selectivo. En este caso, una exploración de tabla secuencial es más barata que una operación de búsqueda de índice / búsqueda de fila. Por lo general, una exploración de tabla hace un uso exhaustivo de E / S secuenciales, que es mucho más rápido que las lecturas de acceso aleatorio.

A menudo, si una consulta devuelve más que solo un pequeño porcentaje de filas, será más barato hacer un escaneo de tabla que una búsqueda de índice / búsqueda de fila u operación similar que haga un uso intensivo de E / S aleatorias.


1

Solo para agregar, lo que encontré. Si lo haces:

create view vMyTable_Combined as
select *, 1 AS [Active] from MyTable_Active
union all
select *, 0 AS [Active] from MyTable_Archive

Luego puede filtrar en el campo [Activo] y asegurarse de que la otra parte no esté cargada.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.