Índices no agrupados: claves y no claves

8

Solo quiero asegurarme de que estoy en el camino correcto con estos conceptos, por lo que cualquier comentario sería muy apreciado.

Aquí está mi teoría de la consulta que acabo de optimizar, a través de un proceso de prueba y error y leyendo la documentación de MSDN.

La consulta

DECLARE @pic_id int
SET pic_id = 1

SELECT ROW_NUMBER() OVER (ORDER BY pic_date desc) AS row_num, *
FROM tbl_pics
WHERE deleted = 0 AND map_id = 1 AND (hidden = 0 OR pic_id = @pic_id)

El índice

CREATE NONCLUSTERED INDEX [IX_tbl_pics] ON [dbo].[tbl_pics] 
(
    [map_id] ASC,
    [deleted] ASC,
    [pic_date] DESC
)
INCLUDE ( [hidden], [pic_id] )

También hay un índice PK en pic_id

La teoría

Las columnas clave son así, porque se usan en una cláusula WHERE (pero no en una situación OR) o en ORDER BY.

Las columnas sin clave (INCLUIR) como tal, porque se usan en el DÓNDE, pero porque se usan en un escenario OR no pueden (no pueden = no mejorarán el rendimiento) ser una columna clave.

¿Son correctas estas presunciones? Si no, ¿qué me estoy perdiendo?

¡Gracias!

Darthtong
fuente

Respuestas:

8

Le está pidiendo al optimizador de consultas que produzca un plan que pueda responder la consulta:

SELECT *
FROM tbl_pics
WHERE deleted = 0 AND map_id = 1 AND hidden = 0;

El resto es pelusa (incluido el OR pic_id = @pic_id). Esta será una exploración de tabla, garantizada, debido a la baja selectividad de los predicados involucrados (estoy seguro deletedy hiddenson 0/1, y map_ipdudo que tenga algún impacto significativo). El único predicado que podría salvar la consulta es, pic_id = @pic_idpero al colocarla en una condición OR, eliminó su posibilidad. Ningún índice secundario puede ayudarlo, de manera realista. La adición de ROW_NUMBER anunciará un tipo, muy probablemente, pero el daño real es el escaneo.

Esta es una causa perdida. Presentar requisitos realistas.

Remus Rusanu
fuente
6

¿La clave principal también es el índice agrupado? Si es así, no hay razón para hacerlo INCLUDE (pic_id)porque el índice agrupado único ya se utilizará como marcador en el índice no agrupado.

En cuanto a lo que está hablando con el quirófano, eso es efectivamente una segunda parte del DÓNDE, pero solo confía en la selectividad del primero para hacer la mayor parte del trabajo (mientras confía en INCLUIR para evitar ir a la mesa).

Pero al tener * allí, puede que tenga que ir a la mesa de todos modos.

Por otro lado, es posible que no esté diseñando mis índices basados ​​en una sola consulta a menos que esta consulta se use mucho sin tener en cuenta más de la carga. Y aún echar un vistazo al plan de ejecución no podía hacer daño.

Cade Roux
fuente