2010-01-21 13 views
6

voy a ejecutar una consulta y se incluye el plan de ejecución real. Hay un Hash Match que me interesa porque su subárbol usa un Index Scan en lugar de una búsqueda de índice. Cuando muevo el mouse sobre este Hash Match, hay una sección llamada "Probe Residual". Había asumido que este es el valor al que me estoy sumando. ¿Estoy en lo correcto aquí o hay una mejor explicación de lo que eso significa?pregunta sobre cómo leer un plan de ejecución de SQL

La segunda pregunta que tuve es con respecto a los índices que utiliza. En mi ejemplo, estoy bastante seguro de que esta unión en particular se está uniendo en dos columnas. El índice que escanea tiene ambas columnas, así como otra columna que no se usa en la combinación. Tenía la impresión de que esto daría como resultado una búsqueda de índice en lugar de un escaneo. ¿Me equivoco en esto?

Respuesta

4

Una combinación hash por lo general (siempre?) Utiliza una exploración o al menos un rango de exploración. Una combinación hash funciona escaneando tablas de combinación izquierda y derecha (o un rango en las tablas) y construyendo una tabla hash en memoria que contiene todos los valores 'vistos' por los escaneos.

Lo que sucedió en su caso es esto: la QO notó que puede obtener todos los valores de una columna C de un índice no agrupado que contiene esta columna (como clave o como columna incluida). Ser un índice no agrupado es probablemente bastante limitado, por lo que la cantidad total de IO para escanear todo el índice no agrupado no es exagerado. El QO también consideró que el sistema tiene suficiente RAM para almacenar una tabla hash en la memoria. Cuando se compara el costo de esta consulta (un escaneo de un índice no agrupado de extremo a extremo para, digamos, 10000 páginas) con el costo de un ciclo anidado que usa búsquedas (digamos 5000 sondeos de 2-3 páginas cada una) El escaneo ganó porque requiere menos IO. Por supuesto, es en gran parte especulación de mi parte, pero estoy tratando de presentar el caso desde el punto de vista de QO, y el plan es probablemente óptimo.

Los factores que contribuyeron a esta elección plan en particular serían:

  • un gran número de candidatos estimados en el lado derecho de la unión
  • disponibilidad de la columna de combinación en un índice reducido no agrupado para el lado izquierdo
  • montón de memoria RAM

Para una gran estimación del número de candidatos, una mejor opción que la combinación hash sólo es la fusión a unirse, y que uno requiere que la entrada sea clasificada previamente. Si el lado izquierdo puede ofrecer una ruta de acceso que garantice un pedido en la columna unida y el lado derecho tiene una posibilidad similar, entonces puede terminar con la combinación de fusión, que es la unión más rápida.

+3

Una coincidencia hash no utiliza necesariamente un escaneo. Puede involucrar fácilmente una Búsqueda en registros particulares y luego usar los resultados de esa Búsqueda en la Partida Hash. Para un bucle anidado, está manejando un registro a la vez, por lo que es más probable que prefiera una búsqueda, pero eso no significa que un hash prefiera un escaneo, solo necesita obtener todas las filas que sean posibles. Si está filtrando en ambas tablas involucradas y tiene un índice de cobertura pero también un cálculo, puede reproducir este comportamiento. –

+0

@Rob: No estoy vendido en eso. Me tomó un tiempo encontrar una referencia pública disponible, pero lea http://blogs.msdn.com/craigfr/archive/2006/08/10/687630.aspx sobre cómo funciona el Hash-Join, tanto la compilación como la sonda fase * lea la entrada completa en una pasada * qué tipo de reglas busca. Además, el pseudo-algoritmo establece claramente que no existe una correlación entre los lados izquierdo y derecho que determina el filtrado de la sonda. –

+0

Derecha ... consideremos primero la instalación. Crea dos tablas, con dos campos cada una. Índice uno en el campo de filtro, incluida la columna de campo de unión. A continuación, los llenaremos con números. crear tabla dbo.table1 (id int identity (1,1) clave principal , joinfield int , filterfield int ); ir create table dbo.table2 (id int identity (1,1) clave principal , joinfield int , filterfield int ); ir crear índice ix1 en dbo.table1 (filterfield) include (joinfield); crear índice ix2 en dbo.table2 (filterfield) include (joinfield); ir –

4

This blog post will probably answer your first question.

cuanto a la segunda, exploraciones de índices puede ser seleccionado por el optimizador en una serie de situaciones. De la parte superior de mi cabeza:

  • Si el índice es muy pequeña
  • Si se seleccionará la mayor parte de las filas en el índice por la consulta

  • Si está utilizando funciones en el dónde cláusula de la consulta

para los dos primeros casos, es más eficiente para hacer una exploración, por lo que el optimizador elige lo largo de un buscar. Para el tercer caso, el optimizador no tiene otra opción.

+0

Muy buen artículo, gracias por publicarlo. Entonces, ¿está diciendo que si la primera columna indexada no se une a mi consulta, podría dar como resultado una exploración de índice en lugar de una búsqueda? –

+1

Sí. Por cierto, su blog es realmente bueno para aprender sobre el funcionamiento interno del servidor sql. – womp

+0

Sí, quedé impresionado con lo que leí allí. Agregándolo a mi lista. ¡Gracias por apuntarme hacia él! –

2

1/A Hash Match significa que se necesita un hash de columnas utilizadas en una unión de igualdad, pero debe incluir todas las otras columnas involucradas en la unión (para>, etc.) para que también puedan verificarse. Aquí es donde entran en columnas residuales.

2/Un Index Seek se puede hacer si se puede ir directamente a las filas que desee. ¿Quizás estás aplicando un cálculo a las columnas y usando eso? Luego usará el índice como una versión más pequeña de los datos, pero aún deberá verificar cada fila (aplicando el cálculo en cada una).

Cuestiones relacionadas