Respuestas:
¿Debo comenzar a indexar desde el principio o cuando surja un problema de rendimiento?
La estrategia de indexación tiende a evolucionar a medida que surgen patrones de uso. Dicho esto, también hay estrategias y pautas de diseño que se pueden aplicar por adelantado.
Elija una buena clave de agrupación . Por lo general, puede determinar el índice agrupado apropiado en el momento del diseño, en función del patrón esperado de inserciones en una tabla. Si surge un caso convincente para un cambio en el futuro, que así sea.
Crea tus principales y otras restricciones únicas . Estos serán aplicados por índices únicos.
Cree sus claves foráneas e índices no agrupados asociados . Las claves foráneas son las columnas de unión a las que se hace referencia con mayor frecuencia, por lo que debe indexarlas desde el principio.
Cree índices para cualquier consulta obviamente altamente selectiva . Para los patrones de consulta que ya conoce, será altamente selectivo y probablemente usará búsquedas en lugar de escaneos.
Más allá de lo anterior, adopte un enfoque gradual y holístico para implementar nuevos índices. Por holístico, me refiero a evaluar el beneficio potencial y el impacto de todas las consultas e índices existentes al evaluar una adición.
Un problema no infrecuente en los círculos de SQL Server es la sobreindexación, como resultado de la orientación de los indicios de índice DMV y SSMS que faltan. Ninguna de estas herramientas evalúa los índices existentes y sugerirá alegremente que cree un nuevo índice de 6 columnas en lugar de agregar una sola columna a un índice de 5 columnas existente.
-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
)
-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
Kimberly Tripp tiene un excelente material sobre estrategia de indexación que si bien SQL enfocado es aplicable a otras plataformas. Para la gente de SQL Server, hay algunas herramientas útiles para identificar duplicados como el ejemplo anterior.
También podemos crear un índice temporal mientras ejecutamos una consulta. ¿Cuáles son los pros y los contras de tales técnicas?
Esto generalmente solo se aplica a consultas raramente ejecutadas, generalmente ETL. Necesitas evaluar:
Realmente hay riesgos asociados con ambos enfoques:
Opción a) Indice desde el principio, pero no se dé cuenta de que ha creado una serie de índices que nunca se utilizan. Estos agregan algo de sobrecarga (más notablemente a las consultas que modifican los datos, pero también con la optimización de las instrucciones SELECT que intentan identificar el mejor índice).
Tendrá que disciplinarse para identificar los índices que ya no se usan e intentar eliminarlos (PostgreSQL puede hacer esto; desafortunadamente, MySQL, en comparación, es muy débil en este momento).
Opción b) No agregue índices hasta que las personas comiencen a quejarse, o sus herramientas de diagnóstico activen que ciertas consultas son lentas y podrían mejorarse.
El riesgo que presenta es que no tiene una ventana de tiempo suficientemente grande entre cuando nota que necesita el índice y cuando tiene que agregarlo.
PostgreSQL admite la creación de índices CONCURRENTLY
, lo que reduce parte del estrés de este requisito de agregar un índice repentino, pero hay algunas advertencias que se mencionan en el manual.
La opción (b) tiende a ser mi preferencia, pero creo que un híbrido de ambas opciones es probablemente la mejor solución. Tiene que ver con su nivel de confianza en cuanto a si cree que realmente se utilizará un índice.
Lo que hace que esta discusión sea particularmente compleja es que, por lo general, es fácil cambiar los índices, pero es más difícil cambiar el esquema. No quiero promover la reacción tardía de b como una excusa para ser imprudente.
Además de la respuesta de Mark
Puede tener una idea al tener datos de prueba realistas en las cantidades esperadas. He visto muchos, muchos (demasiados) casos en los que una consulta se ejecuta bien con 1000 filas pero no el millón en producción.
Si puede, trabaje en una copia de producción más adelante,
Por supuesto, he visto el extraño problema solo en la producción debido a los patrones de uso cuando todo lo demás es idéntico
Índices temporales? Fuera de los patrones de carga ETL, si los necesita una vez, los necesitará nuevamente. No olvide: un índice crear / soltar es una escritura y se registra = más carga
Solo para agregar algunas cosas.
Este es mi enfoque.
No tenga miedo de poner > 0
o > ""
en sus cláusulas where para columnas no utilizadas.
select * from blah
where A="one"
and B="two"
and C>="" --to match index
and D="four"
--This will use your existing index. No need to create a redundant one.
Trataré de responder solo la primera pregunta. Si puede estimar incluso aproximadamente desde el principio cuántos registros tendrá en sus tablas después de un cierto período de tiempo, entonces diría que es mejor comenzar desde el principio para diseñar algunos índices. Intente utilizar algunas herramientas de prueba o scripts de prueba que automatizarán tantas llamadas como sea posible para las llamadas de aplicación que cree que se usarán con mayor frecuencia y verá qué escaneos de tabla se pueden evitar desde el principio.
Al principio será un trabajo de adivinanzas, pero con el tiempo, ya que tiene estadísticas de uso adecuadas, tendrá una imagen más clara.