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.