Son muchos los mails que recibo y contesto en modo privado con preguntas relacionadas con "buenas prácticas" para nuestro entorno de Base de Datos.
Ya hemos hablado sobre el tema en post anteriores mas, en lo personal, creo que debemos seguir "machacando" una y otra vez sobre estas buenas prácticas para que nuestra vida como DBA's no sufra evitables y molestas desventuras...
Hagamos entonces un breve repaso de buenas prácticas, como siempre quedo a vuestra disposición, saludos cordiales desde Argentina.
1. Diseñando las bases con el máximo grado de
normalización posible.
* Elimine los grupos repetidos de las tablas
individuales.(redundancia)
* Cree una tabla independiente para cada
conjunto de datos relacionados
* Identifique cada conjunto de datos
relacionados con una clave principal.
* Relacione estas tablas con una clave externa.
* Elimine los campos que no dependan de la
clave.
2. Utilizando el Isolation Level más laxo acorde
nuestras regla de negocio
·
Si
nuestras reglas de negocio permiten realizar lecturas sin loqueo, conocidas
como “lecturas sucias”, podemos entonces
setear nuestro Isolation Level en “Read Uncomitted” o bien utilizar el hint “no
lock “
·
Hay
también otras alternativas intermedias entre el IL por default y el Read
Uncomitted, por ejemplo el que permite la lectura por versionado llamado
“Read_Uncomitted_Snapshot”
3. Programando queries performantes
3.1) Seleccionando la menor cantidad de datos posibles. (ser muy selectivo en los
campos a filtrar, en los where, en los having…)
3.2) Manteniendo las transacciones chicas.
(un Select no tiene por qué formar parte de transacción )
3.3) Utilizando
datos del mismo tipo para comparaciones y joins de tablas evitando así
conversiones implícitas-
3.4) Reemplazando
cursores por el uso de While+Tablas temporales o Tablas variables http://www.sqlbook.com/advanced/sql-cursors-how-to-avoid-them/
3.5) Utilizando
los campos indexados para los campos select, las cláusulas where, los
joins, lor order by, group by…
3.6) No
permitiendo interacciones de usuarios dentro de las transacciones (cualquier
transacción que permanezca abierta esperando un input de un user es bloqueante)
3.7) Utilizando Métodos “Set – Based” por sobre
“Procedural Methods” https://www.codeproject.com/Articles/34142/Understanding-Set-based-and-Procedural-approaches
3.8) Estudiar
Planes de Ejecución y otimizando las queries y atacando las queries +
lentas
3.9) Eliminando
los Order By cuando no son
necesarios
3.10) Disminuyendor al Máximo el Uso de
Funciones del Sistema (por ejemlplo la función max(), genera un scant table
más allá del que el campo esté o no idx.
3.11) Utilizando los Hints Necesarios
3.12) Evitando bloqueos de recursos por borrados
masivos de datos. A veces en mucho menos perjudicial para el sistema el
generar una tabla nueva con los datos online que el borrar los datos que
queremos deprecar de una tabla mediante el uso de un delete
3.13) Evitando “Chatty Aplications”. Se conoce
como Chatty App aquellas que commitean data en reiteradas ocasiones en lugar de
hacerlo una vez. (por ejemplo formularios de suscripción web que validan cada
dato que el user va llenando)
4. Dotando a las tablas de los índices necesarios
4.1) Una buena indexación es aquella que es
funcional a los procedimientos y que no excede las necesidades reales.
4.2) Seleccionando los campos más “chicos” en
términos de “tipo de datos” (un idx
debería ser hecho sobre un campo integer o datetime mientras su utilidad
sería muy poca en campos del tipo varchar)
4.3) Eliminando
aquellos índices que NO son necesarios (recordemos que todo índice tiene
asociado un costo de mantenimiento y
almacenamiento además de atentar contra la performance en caso de inserciones
sobre tablas sobreindexadas)
4.4) Generando
e Implementando Rutinas de Mantenimiento de Indices (es muy importante que
los índices se mantengan desfragmentados, especialmente en entornos oltp)
4.5) Utilizando Indices Cubiertos, para
consultas en las que puedan eliminarse key lookups, incluyendo campos del
select en forma lógica con la cláusula “include”
5. Generando Rutinas de Mantinimiento de Estadísticas
5.1) Las estadísticas son importantísimas para
que nuestros planes de ejecución elijan la mejor alternativa para ejecutar una
query. Tengan en cuenta que si bien Microsoft nos da la chance de setear su
actualización automáticamente dicha actualización no es efectiva. Utilicen una
rutina para tal fin. La pueden encontrar también en este blog
6. Implementando el Pariticionado de Tablas
6.1) El
particionar tablas puede agilizar mucho nuestras consultas en tablas que
necesitan mantener grandes cantidades de datos históricos on line y que por lo
tanto tienen varios millones de registros.
Si en este tipo de tablas, existen consultas donde se puede llegar a
necesitar datos históricos y actuales de un cliente (por ejemplo la consulta
histórica de la cuenta corriente de una empresa), pues bien, sería una buena
idea particionar por año y generar, distribuir datafiles en distintos discos y
generar lecturas paralelas. OJO NO ABUSAR
de las PARTCIONES, ya que su mantenimiento es complejo (más de todo este
tema en este blog)
7. Distribuyendo los datafiles de nuestra base de datos correctamente
7.1) El gran punto fuerte del SQL
Server es la posibilidad de realizar lectoescrituras paralelas Para ello un
escenario ideal es el tener separado en unidades físicas diferentes:
- El OS
- El motor de Base de
Datos
- Los archivos de Datos
- Los archivo de índices
- Los archivos de log.
7.2) Una vez hecho esto el analizar
la carga de los discos (i/o) valiéndose del perfomance monitor y, llegado el caso,
dettachar y reubicar los files que sean necesarios:
8. Seteando la instancia del motor de base de datos del modo más eficaz posible.
Seteos como Memoria
Asignada / Máx grado de paralelismo / Uso de Procesadores etc son sumamente importantes para
la performance y estabilidad de nuestro sistema. Es importante lograr la mejor
configuración para los mismos y revalidarla acorde al control permanente que
debemos hacer sobre las bases y su estabilidad y performance.
9. Manteniendo on line solo la data necesaria
El realizar el pase a files “off
line” o bien a backups, es una tarea que si la reglas de negocio la permiten
debería ser planificada y ejecutada con periodicidad.
10. Evitando la
fragmentación física de los discos
Es muy importante que tengamos
corriendo en períodos de baja o nula concurrencia alguna herramienta eficiente
de desfragmentado de nuestros hard disk.
11. Monitoreando permanentemente nuestro servidor y base de datos
Es vital la uilización del
performance monitor y el event viewer y el establecimiento de baselines..Las
vistas del sistema son también aliados excluyentes para el monitoreo y el
traceo de posibles deficiencias El revisar logs y utilizar trazas "server side"es algo fundamental.