He hecho esto en índices específicos antes de ahora, para ayudar a realizar consultas pesadas a menudo. Efectivamente, lo que han hecho es crear múltiples índices agrupados: cuando cualquiera de esos índices se utiliza para buscar filas, no se necesita trabajo adicional para buscar el resto de los datos en el índice agrupado real (o el montón si no hay un índice agrupado real) .
¿Es esta una estrategia sensata?
Para algunos índices donde sea necesario para admitir ciertos patrones de consulta, ciertamente sí.
Pero para hacer esto con todos los índices, diría que no.
Va a ser un desperdicio de espacio para hacer donde no se necesita realmente, y ralentizará las inserciones / actualizaciones de manera significativa. Puede ralentizar tantas consultas de lectura como sea útil, ya que cada página de índice contiene menos registros, por lo que cualquier consulta que necesite hacer referencia a un fragmento del índice para filtrar pero no usar todas las demás columnas tendrá que acceder a más páginas. Esto hará que su base de datos tenga más memoria: esas páginas deberán cargarse en el grupo de búferes, expulsando potencialmente otras páginas útiles si la memoria es baja. Si se utiliza la compresión en esos índices para intentar mitigar el efecto sobre el almacenamiento y los requisitos de memoria, en su lugar, se cargará una carga adicional a las CPU.
ya que el acceso es a través de un ORM que por defecto (pero no siempre) recupera todas las columnas
Este es un patrón común con un uso poco optimizado de un ORM (o simplemente ORM ingenuos) y en estos casos he visto que el asesor de índices de SQL Server (y herramientas similares de terceros) sugieren índices con muchas INCLUDE
columnas d, por lo que estaría de acuerdo con su sugerencia de que es por eso que los índices se han creado de esta manera.
Pero aunque puede hacer que todas esas consultas sean un poco más rápidas y algunas de ellas significativamente más rápidas, sospecho que en muchos casos cualquier beneficio es tan pequeño que no valdrá la huella de memoria adicional requerida por su conjunto de trabajo común, el espacio en el disco y El IO entre el disco y la memoria.
También recuerde que el ORM podría no estar seleccionando todas las columnas de todas las tablas que toca una consulta, por lo que el beneficio solo puede mantenerse para el objetivo principal de la solicitud actual, y los índices más grandes pueden penalizar la consulta cuando se usan otros objetos para filtrar pero no devuelve datos ( SELECT * FROM table1 WHERE id IN (SELECT someID FROM table2 WHERE someColumn='DesiredValue')
tal vez).
Otra consideración para el exceso de espacio utilizado, particularmente si los datos son grandes, es que tendrá un impacto en su estrategia de respaldo: costos de almacenamiento y transferencia para esos respaldos, tiempos potenciales de restauración, etc.
¿deberíamos estar preparados para cualquier diferencia entre los dos [on-prem y AzureSQL]
En general, creo que las consideraciones aquí serán las mismas en cada caso, aunque cualquier exceso de memoria / costo de IO impuesto por los índices grandes puede ser más directamente visible en Azure, donde puede ajustar el nivel de servicio y, por lo tanto, el costo de la infraestructura es más fácil que teniendo un conjunto relativamente fijo de recursos de hardware. Si usa niveles estándar / premium en lugar de precios basados en vcore, se verá más afectado por el costo de IO en estándar, ya que premium incluye significativamente más IO por DTU. Si usa copias de seguridad de varias regiones o redundancia u otras características no locales en Azure, puede haber un costo de ancho de banda asociado con el espacio adicional que ocupan los índices innecesariamente anchos.
SELECT
sin especificar,ORDER BY
comenzó a devolver las mismas filas que antes pero con un orden arbitrario diferente.En la mayoría de los casos, esta no es una estrategia sensata. La razón es que, en general, en las bases de datos OLTP, las filas devueltas al usuario final no serán muchas. (Generalización)
La pregunta que debe hacerse es, si está buscando en las columnas clave, ¿cuántas filas devolverá esa operación de búsqueda? Y repita eso para las consultas que buscan en esa columna.
Considere la siguiente tabla, que devuelve muchas columnas,
where SelectiveIDField= ...
Si
selectiveIDField
la búsqueda activa solo devuelve una fila , ¿la búsqueda adicional de claves es algo tan malo? (suponiendo que tiene índices agrupados aquí, de lo contrario, búsqueda RID)Solo hará una búsqueda de clave adicional, una ejecución adicional + el operador de combinación. Incluso si es 10 o incluso 100, ¿sería un impacto tan grande? Esto también depende de cuánto se ejecuta su consulta y qué tan importante es el tiempo de ejecución.
En el caso de que sea insignificante, solo cree el índice
SelectiveIDField
y llámelo un día, no debería valer la pena las ganancias de lectura en comparación con las pérdidas de escritura.En resumen, en mi opinión, la creación de índices en toda la tabla no debería ser un enfoque predeterminado a menos que realmente vea un problema con una consulta y pueda mejorarlo drásticamente agregando un índice de cobertura completo.
fuente