none
Duda sobre Indices RRS feed

  • Pregunta

  • Estimados.

    Quiero tratar de entender la creación de indices con este ejemplo:

    SELECT P.Pais,c.ciudad
    FROM Pais P INNER JOIN Ciudad C
    ON P.IdPais = C.IdPais
    WHERE p.pais = 'Francia'

    1.- Creo indice por Idpais en ambas tablas pues los utilizo para el JOIN

    2.- Necesito un indice por pais ua que filtro por Francia, duda, lo agregro como include en el indice que cree en el punto anterior, esta correcto no ?

    3.- Dado que ene le Select muestro las columnas: Pais y Ciudad las debo incluir en un indice aparte o no es necesario.


    DBA SQL Server Santiago/Chile

    lunes, 5 de febrero de 2018 17:57

Respuestas

  • Si el IdPais es la clave primaria de Paises, entonces, salvo que expresamente hayas indicado lo contrario al crear la tabla, te habrá creado un índice agrupado (clustered) sobre ese campo. Eso implica que no tienes que crear un índice sobre ese campo porque ya existe, y que tampoco necesitas el INCLUDE sobre el campo Pais porque ya está incluido en el índice clustered. Si la tabla de países tuviese muchísimos países es posible que te interesase crear un índice no-agrupado sobre el campo Pais para poder filtrar en el Where, pero con el número de países que probablemente vas a tener no compensa, probablemente el optimizador de consultas lo despreciará y te hará un clustered index scan (pero puedes hacer la prueba y verificarlo con el plan de ejecución desde SSMS).

    En la tabla de ciudades sí que deberías poner un índice no-agrupado sobre el campo IdPais (que presumiblemente no es la clave primaria), para facilitar el JOIN. Si en ese índice haces un INCLUDE del campo Ciudad (para que cubra la consulta -- es decir, aporte la información que falta para las columnas del select) entonces se acelerará considerablemente la consulta porque no requerirá saltar del índice no-agrupado al agrupado.

    • Propuesto como respuesta Juan MondragónModerator martes, 6 de febrero de 2018 16:02
    • Marcado como respuesta CMAPM martes, 6 de febrero de 2018 19:40
    lunes, 5 de febrero de 2018 20:20

Todas las respuestas

  • la creación de indices es directamente proporcional a la necesidad de velocidad en determinadas consultas.

    Dicho esto usando las herramientas de sql server de analisis de planes de consulta esta herramientas te indicará que indices deberías tener para incrementar las consultas que analices.

    Dicho ahora de otra manera, si necesitas incrementar la velocidad en determinadas consultas que detectas que son costosas en tiempo, deberías ver que campos usas en dichas consultas para el filtrado y para las intersecciones de datos en ambas tablas, esto es ver que campos comunes usas en las clausulas join y que campos usas para filtrar los datos de la consulta. Una vez aisles estos campos debes valorar si la creación del indice te ayudará a acelerara a consulta y valorarlo pues, evidentemente nada es gratis y crear indices en tablas también tiene su penalización en tamaño de las bases de datos y velocidad.

    Para la consulta que pones de ejemplo yo crearia un indice por pais y ciudad en la tabl de ciudades., de manera que al filtrar por un pais tendria sus ciudades muy rapidamente.

    Además mejoraria la consulta intentando primero obtener el codigo de pais  y pasandolo a la consulta directamente sobre la tabla de ciudades, sin usar join me da que sin usar la join la optimización de esa consulta seria abismal.


    lunes, 5 de febrero de 2018 19:58
  • Si el IdPais es la clave primaria de Paises, entonces, salvo que expresamente hayas indicado lo contrario al crear la tabla, te habrá creado un índice agrupado (clustered) sobre ese campo. Eso implica que no tienes que crear un índice sobre ese campo porque ya existe, y que tampoco necesitas el INCLUDE sobre el campo Pais porque ya está incluido en el índice clustered. Si la tabla de países tuviese muchísimos países es posible que te interesase crear un índice no-agrupado sobre el campo Pais para poder filtrar en el Where, pero con el número de países que probablemente vas a tener no compensa, probablemente el optimizador de consultas lo despreciará y te hará un clustered index scan (pero puedes hacer la prueba y verificarlo con el plan de ejecución desde SSMS).

    En la tabla de ciudades sí que deberías poner un índice no-agrupado sobre el campo IdPais (que presumiblemente no es la clave primaria), para facilitar el JOIN. Si en ese índice haces un INCLUDE del campo Ciudad (para que cubra la consulta -- es decir, aporte la información que falta para las columnas del select) entonces se acelerará considerablemente la consulta porque no requerirá saltar del índice no-agrupado al agrupado.

    • Propuesto como respuesta Juan MondragónModerator martes, 6 de febrero de 2018 16:02
    • Marcado como respuesta CMAPM martes, 6 de febrero de 2018 19:40
    lunes, 5 de febrero de 2018 20:20
  • Gracias nuevamente.

    DBA SQL Server Santiago/Chile

    martes, 6 de febrero de 2018 19:40