0% encontró este documento útil (0 votos)
119 vistas7 páginas

Optimización de SQL Server

Cargado por

Stephen Fuller
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
119 vistas7 páginas

Optimización de SQL Server

Cargado por

Stephen Fuller
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 7

Optimización de SQL Server (SQL Server Tuning)

Para poner a punto SQL Server es necesario ajustar la configuración, opciones, y valores de setup
basadas en las observaciones de las características de trabajo del servidor. Típicamente estas
observaciones se hacen durante el periodo de trabajo mas critico de servidor para perfeccionar las
cargas de trabajo más pesadas. Las recomendaciones de afinación siguientes son aquéllas que
generalmente tienen el mayor impacto en el trabajo de Servidor. Sin embargo, la aplicación de estas
recomendaciones puede producir resultados diferentes que dependen del ambiente particular del
Servidor.

Memoria

La memoria de SQL Server esta dividida en dos espacios, el cache de procedimientos, y el cache de
datos. El Servidor SQL distribuye eficazmente la memoria entre el cache de procedimiento y el cache de
datos usando los parámetros de configuración del cache de procedimiento. La distribución de la
memoria restante entre procedimientos y datos, se encarga de mantener los objetos mas usados en sus
respectivos caches de memoria. Por consiguiente, los procedimientos almacenados mayormente usados
deben estar en el cache de procedimientos, mientras que la mayoría de índices y tablas usadas mas
frecuentemente deben estar en el cache de datos.

La mejor manera de determinar cómo es usada la memoria por el Servidor de SQL es ejecutar DBCC
MEMUSAGE. Esta sentencia indica la cantidad de memoria asignada al Servidor de SQL en el comienzo,
los 12 objetos más grandes en el cache de procedimientos, y los 20 objetos más grandes en el cache de
datos. Por consiguiente, las recomendaciones son basadas en el uso de estos datos que determinaran el
tamaño óptimo para los caches.

Optimizando el Cache de Datos

El cache de datos está compuesto de la memoria sobrante del Servidor de SQL una vez que los requisitos
del cache de procedimiento han sido satisfechos. Lo mejor es tener bastante espacio del cache para
contener la mayoría  los índices usados y un porcentaje respetable de las tablas mas accedidas
frecuentemente, reduciendo las entradas/salidas físicas. Usted también puede usar la sentencia DBCC
MEMUSAGE para ver los 20 objetos más grandes del cache de datos y puede determinar un tamaño
considerable para el cache de datos basado en los tamaños de estos objetos. Usted también puede
determinar el tamaño de las tablas e índices accedidas mas frecuentemente aplicando las fórmulas del
tamaño cedidas por Appendix A of Microsoft SQL Server Administrator's Companion. Habiendo
calculado estos tamaños, usted puede elegir asignar bastante memoria al Servidor de SQL y contener la
íntegramente los objetos de las bases de datos en el cache.

Optimizando el Cache de Procedimientos.

Al poner a punto el cache de procedimiento, lo mejor es determinar el tamaño óptimo para contener los
procedimientos almacenados  más activos. En realidad lo que se busca es prevenir las lecturas a
procedimientos almacenados en disco porque esto es muy costoso. Es más, si el cache de procedimiento
es bastante grande , los procedimientos no se descargaran del cache por los nuevos procedimientos
cargados en el. (Recuerde que el Servidor de SQL guardará una copia duplicada de cada procedimiento
que se accede por más de un usuario.) por defecto, el Servidor de SQL distribuye 30 por ciento de
memoria disponible al cache de procedimientos después que el kernel de SQL se ha asignado. La tarea
es determinar si este 30 por ciento es poco, suficiente, o demasiado basado en el tamaño de objetos del
cache de procedimientos. Es importante no disminuir el cache de procedimientos debajo de 5 por
ciento.

Usted puede determinar si el cache de procedimientos es bastante grande ejecutando los


procedimientos almacenados mas frecuentemente usados y ejecutando la sentencia DBCC MEMUSAGE;
esto mostrara los 12 procedimientos almacenados más grandes en el cache de procedimientos. Si usted
tiene más de 12 procedimientos almacenados, puede continuar ejecutando los demás procedimientos y
ejecutar cada vez la sentencia DBCC MEMUSAGE para ver si uno de los procedimientos previamente
ejecutados ha permanecido en el cache. Usted también puede ejecutar cada procedimiento almacenado
y obtener su tamaño de ejecución usando DBCC MEMUSAGE. Después de que usted ha ejecutado todos
los procedimientos que son llamados con mas frecuencia y ha obtenido sus tamaños, sume éstos valores
y obtenga el tamaño total necesario del cache para todos los procedimientos.

TEMPDB en RAM

Las consultas ejecutadas contra el Servidor de SQL que usan espacio de trabajo temporal como las
operaciones, GROUP BY, tablas temporales, uniones de tablas (JOIN), son beneficiadas si la tempdb se
encuentra en RAM. Sin embargo, para poner la tempdb en RAM, usted debe tener mas memoria
disponible que la asignada a Windows NT Server y SQL Server. Por consiguiente, si la tempdb esta
actualmente en 25 MB de tamaño, entonces la memoria total requerida para el sistema es: 16 MB para
el Windows NT más (XX) la memoria para SQL Server mas 25 MB para el tempdb.

Distintas formas de optimizar las consultas realizadas en SQL.


El lenguaje SQL es no procedimental, es decir, en las sentencias se indica que queremos conseguir y no
como lo tiene que hacer el interprete para conseguirlo. Esto es pura teoría, pues en la práctica a todos
los gestores de SQL hay que especificar sus propios truquitos para optimizar el rendimiento.

Por tanto, muchas veces no basta con especificar una sentencia SQL correcta, sino que además, hay que
indicarle como tiene que hacerlo si queremos que el tiempo de respuesta sea el mínimo. En este
apartado veremos como mejorar el tiempo de respuesta de nuestro interprete ante unas determinadas
situaciones:

Diseño de las tablas

 Normaliza las tablas, al menos hasta la tercera forma normal, para asegurar que no hay
duplicidad de datos y se aprovecha al máximo el almacenamiento en las tablas. Si hay que
desnormalizar alguna tabla piensa en la ocupación y en el rendimiento antes de proceder.
 Los primeros campos de cada tabla deben ser aquellos campos requeridos y dentro de los
requeridos primero se definen los de longitud fija y después los de longitud variable.
 Ajusta al máximo el tamaño de los campos para no desperdiciar espacio.
 Es muy habitual dejar un campo de texto para observaciones en las tablas. Si este campo se va
a utilizar con poca frecuencia o si se ha definido con gran tamaño, por si acaso, es mejor crear
una nueva tabla que contenga la clave primaria de la primera y el campo para observaciones.

Gestión y elección de los índices

Los índices son campos elegidos arbitrariamente por el constructor de la base de datos que permiten la
búsqueda a partir de dicho campo a una velocidad notablemente superior. Sin embargo, esta ventaja se
ve contrarrestada por el hecho de ocupar mucha más memoria (el doble más o menos) y de requerir
para su inserción y actualización un tiempo de proceso superior.

Evidentemente, no podemos indexar todos los campos de una tabla extensa ya que doblamos el tamaño
de la base de datos. Igualmente, tampoco sirve de mucho el indexar todos los campos en una tabla
pequeña ya que las selecciones pueden efectuarse rápidamente de todos modos.

Un caso en el que los índices pueden resultar muy útiles es cuando realizamos peticiones simultáneas
sobre varias tablas. En este caso, el proceso de selección puede acelerarse sensiblemente si indexamos
los campos que sirven de nexo entre las dos tablas.

Los índices pueden resultar contraproducentes si los introducimos sobre campos triviales a partir de los
cuales no se realiza ningún tipo de petición ya que, además del problema de memoria ya mencionado,
estamos ralentizando otras tareas de la base de datos como son la edición, inserción y borrado. Es por
ello que vale la pena pensárselo dos veces antes de indexar un campo que no sirve de criterio para
búsquedas o que es usado con muy poca frecuencia por razones de mantenimiento.

Campos a Seleccionar

 En la medida de lo posible hay que evitar que las sentencias SQL estén embebidas dentro del
código de la aplicación. Es mucho más eficaz usar vistas o procedimientos almacenados por que
el gestor los guarda compilados. Si se trata de una sentencia embebida el gestor debe
compilarla antes de ejecutarla.
 Seleccionar exclusivamente aquellos que se necesiten
 No utilizar nunca SELECT * por que el gestor debe leer primero la estructura de la tabla antes
de ejecutar la sentencia
 Si utilizas varias tablas en la consulta especifica siempre a que tabla pertenece cada campo, le
ahorras al gestor el tiempo de localizar a que tabla pertenece el campo. En lugar de SELECT
Nombre, Factura FROM Clientes, Facturacion WHERE IdCliente = IdClienteFacturado, usa:
SELECT Clientes.Nombre, Facturacion.Factura WHERE Clientes.IdCliente =
Facturacion.IdClienteFacturado.

Campos de Filtro

 Se procurará elegir en la cláusula WHERE aquellos campos que formen parte de la clave del
fichero por el cual interrogamos. Además se especificarán en el mismo orden en el que estén
definidos en la clave.
 Interrogar siempre por campos que sean clave.
 Si deseamos interrogar por campos pertenecientes a índices compuestos es mejor utilizar todos
los campos de todos los índices. Supongamos que tenemos un índice formado por el campo
NOMBRE y el campo APELLIDO y otro índice formado por el campo EDAD. La sentencia WHERE
NOMBRE='Juan' AND APELLIDO Like '%' AND EDAD = 20 sería más optima que WHERE NOMBRE
= 'Juan' AND EDAD = 20 por que el gestor, en este segundo caso, no puede usar el primer índice
y ambas sentencias son equivalentes por que la condición APELLIDO Like '%' devolvería todos
los registros.

Orden de las Tablas


Cuando se utilizan varias tablas dentro de la consulta hay que tener cuidado con el orden empleado en
la cláusula FROM. Si deseamos saber cuantos alumnos se matricularon en el año 1996 y escribimos:
FROM Alumnos, Matriculas WHERE Alumno.IdAlumno = Matriculas.IdAlumno AND Matriculas.Año =
1996 el gestor recorrerá todos los alumnos para buscar sus matriculas y devolver las correspondientes.
Si escribimos FROM Matriculas, Alumnos WHERE Matriculas.Año = 1996 AND Matriculas.IdAlumno =
Alumnos.IdAlumnos, el gestor filtra las matrículas y después selecciona los alumnos, de esta forma tiene
que recorrer menos registros.

Preguntas y respuestas acerca de SQL

Errores de E/S, creación de reflejos de la base de datos, etc.

Paul S. Randal

P He empezado a ejecutar comprobaciones de coherencia con regularidad en las bases de datos que
administro e, incluso, he agregado algunas alertas del Agente SQL para localizar los errores de E/S que
se indican en las consultas de los usuarios. No sé si la lógica que he implementado en las
comprobaciones y las alertas funcionará, ya que mis bases de datos no tienen daños. ¿Cómo puedo
crear daños en una base de datos de prueba para asegurarme de que todo lo que he configurado
funciona correctamente? Además, ¿qué más puedo hacer para detectar los errores de E/S?
R En SQL Server® 2000, el truco para crear una base de datos dañada en la que realizar pruebas
consistía en eliminar manualmente una fila de la tabla sysindexes de una base de datos de prueba.
Pero con SQL Server 2005, dañar una tabla del sistema de esta manera es muy difícil. La mejor manera
de dañar una base de datos de prueba es usar un editor hexadecimal para alterar un archivo de datos
con la base de datos cerrada. Estos son los pasos que debe seguir:

 Cierre la base de datos para que los archivos de datos no estén bloqueados. (Tenga cuidado de
no separar la base de datos porque, si daña la página incorrecta, tal vez no pueda unirla de nuevo).
 Elija una parte del archivo de más de 100 páginas aproximadamente (por lo menos de 819.200
bytes) con intervalos de 8.192 bytes (límite de página). De esta forma puede evitar las páginas de
metadatos importantes y los mapas de bits de asignación, lo que le permite iniciar la base de datos y
ejecutar DBCC CHECKDB en ella.
 Escriba algunos bytes de ceros en la parte elegida del archivo. Al usar esta técnica la
introducción de algunos daños en el encabezado de la página está prácticamente garantizada.

Dicho esto, la forma más rápida de dañar una base de datos de prueba es usar una que ya esté creada.
Puede encontrar ejemplos de bases datos dañadas de SQL Server 2000 y SQL Server 2005 (con
explicaciones) en mi blog (en go.microsoft.com/fwlink/?LinkId=115151).
En cuanto a la segunda pregunta con respecto a lo que se debe hacer para detectar los errores de E/S:
debe habilitar las sumas de comprobación de las páginas. Esta característica se introdujo en SQL Server
2005 para proteger una página entera de la base de datos de los errores introducidos por el subsistema
de E/S.

Básicamente, al escribir una página en el disco, lo último que hace SQL Server es calcular una suma de
comprobación de los 8 KB de la página y marcarla en la página. Al leer una página del disco, si tiene una
suma de comprobación de página, se calculará de nuevo y se comparará con la que se almacena en la
página. Si no coinciden, significa que algún elemento ajeno a SQL Server dañó la página y se produce un
error 824. El error se muestra en la conexión que provocó la lectura de la página, además de registrarse
en el registro de error de SQL Server y en el registro de eventos de aplicación de Windows®.

Las sumas de comprobación de página están activadas de forma predeterminada en todas bases de
datos creadas en SQL Server 2005 y SQL Server 2008. Sin embargo, hay que habilitarlas manualmente en
las bases de datos actualizadas a partir de versiones anteriores de SQL Server. Para habilitar las sumas
de comprobación de página, use este código:

Copiar código

ALTER DATABASE mydb SET PAGE_VERIFY CHECKSUM;

Sugerencia: cambie el puerto predeterminado de SQL Server

De forma predeterminada, el puerto configurado de las instancias de SQL Server es el 1433. Una vez que
una instancia use este puerto, no podrá ocuparlo ninguna otra. Por lo tanto, si instala una segunda
instancia (con nombre) de escucha en la red mediante tcp, necesitará otro puerto. En algunos casos, el
administrador puede cambiar el puerto por razones de ofuscación (aunque esta forma de ofuscación es
secundaria y se puede interrumpir fácilmente mediante un escáner de puerto). Por supuesto, deberá
configurar el cliente para usar un puerto diferente. Existen tres enfoques típicos de hacerlo.

Primero, suponiendo que el administrador cambió el puerto de una instancia a 5555, puede especificar
simplemente el número de puerto de la instancia dentro del nombre del equipo al que desea conectar
mediante la sintaxis MiNombreDeServidor,5555. Si se vuelve a cambiar el puerto, los clientes deberán
cambiar sus connectionStrings de nuevo.

Otra opción es usar alias de SQL Server, que se configuran en el cliente. Además de especificar un
nombre de alias, debe indicar el nombre de servidor, el nombre de puerto y el protocolo. Una vez
configurado, el alias se puede usar como nombre de servidor para conectarse a la instancia de la base de
datos. La ventaja que aporta esta opción es que un administrador de dominio puede implementar los
cambios de configuración del servidor, ya que la configuración se almacena en el registro.

La tercera opción de las instancias con nombre en las que el usuario sólo conoce el nombre de la
instancia y especifica el nombre con la estructura NombreDeEquipo\NombreDeInstancia dentro de
connectionString es usar el servicio Explorador de SQL Server. Esto ya se ha implementado en SQL
Server 2000 como parte de un servicio en ejecución. No obstante, en SQL Server 2005, se creó el servicio
Explorador de SQL Server como servicio independiente. Además del descubrimiento de instancias del
equipo, responde a las solicitudes entrantes del protocolo de datagramas de usuario (UDP) en el puerto
1434 con el número de puerto adecuado para la instancia solicitada, lo que permite la redirección del
cliente y la compatibilidad de una conexión transparente.

—Jens K. Suessmeyer, consultor de bases de datos en Microsoft

P Para eliminar la fragmentación de la base de datos, he configurado un plan de mantenimiento


nocturno que regenera todos los índices de la base de datos de producción que se ejecuta en SQL
Server 2005 Enterprise Edition con SP2. He observado que, de esta forma, la base de datos crece
demasiado, por eso, agregué un paso para reducir el espacio extra, ya que no hay mucho espacio en el
disco. Ahora parece que la regeneración no funciona. ¿Qué pasa?

R Se ha encontrado con un problema al que suelen enfrentarse muchos usuarios cuando intentan
configurar un plan de mantenimiento. Ha entrado en un ciclo de reducción y crecimiento.

Al regenerar un índice, se crea una nueva copia del índice antes de eliminar el índice existente. Este
procedimiento necesita espacio extra en los archivos de la base de datos (generalmente el mismo
espacio que use el índice actual). En SQL Server 2000, también se necesita el espacio extra para ordenar
las filas del índice (aproximadamente un 20 por ciento del tamaño del índice), pero ese requisito se ha
eliminado en la regeneración de un índice sencillo en SQL Server 2005.

A veces, los administradores desean quitar el espacio extra creado durante la regeneración del índice,
por lo que realizan una operación de reducción al plan de mantenimiento después de la regeneración.
Sin embargo, poca gente sabe que esta reducción provocará la fragmentación del índice debido a la
naturaleza de su algoritmo. Esto significa que el índice regenerado y desfragmentado recientemente se
fragmentará de inmediato, lo que anulará el efecto de regeneración en primer lugar.

Ya que el archivo de la base de datos volverá a aumentar la próxima vez que se regenere el índice, es
preferible que la base de datos tenga espacio extra y evitar que se ejecute la reducción. (Además, el
continuo crecimiento y reducción de los archivos de la base de datos causará la fragmentación de los
archivos a nivel de sistema operativo, lo que puede provocar un rendimiento insuficiente al igual que la
fragmentación del índice.

Por último, debería plantearse la posibilidad de reducir la frecuencia con que regenera los índices.
Incluso puede tratar de usar un método alternativo, como el antiguo DBCC INDEXDEFRAG que escribí
para SQL Server 2000 o la nueva sintaxis ALTER INDEX REORGANIZE en SQL Server 2005 y SQL Server
2008.

Hay unas notas técnicas de gran utilidad en las que se trata la fragmentación de índices y ofrece
orientación acerca de cuándo eliminar la fragmentación (en go.microsoft.com/fwlink/?LinkId=115154).
Aunque este texto se escribió para SQL Server 2000, los conceptos son los mismos.
P Hemos estado evaluando la estrategia de recuperación de desastres en mi organización y creo que
la creación de reflejos de bases de datos es el procedimiento correcto en nuestra situación. El servidor
que intento proteger tiene muchas bases de datos no relacionadas (resultado de un proyecto previo
de consolidación de servidores) y quiero usar la creación de reflejos de bases de datos para todas. Mi
pregunta es la siguiente: ¿cuántas bases de datos se pueden reflejar antes de que se reduzca el
rendimiento?

R La respuesta a esta pregunta es muy típica: depende. Las directrices publicadas aconsejan no
reflejar más de 10 bases de datos por instancia, pero depende de cada usuario. Hay que tener en
cuenta los siguientes factores para la instalación del hardware:

 ¿De cuánta memoria disponen las instancias principal y reflejada? (Lo idea sería que dispongan
de la misma.)
 ¿Cuánta capacidad de procesamiento tienen las instancias principal y reflejada? (También
debería ser la misma.)
 ¿Cuánto ancho de banda tiene el subsistema de E/S de la instancia reflejada? (Debería tener
tanto como el de la principal.)
 ¿Cuántos registros de transacciones genera la carga de trabajo en cada base de datos?
 ¿Cuánto ancho de banda de red está disponible entre las instancias principal y la reflejada?

Los últimos dos factores son los más importantes. Si el ancho de banda de red disponible entre las dos
instancias no es suficiente para encargarse la velocidad de generación de registros de transacciones
combinados por segundo de todas las bases de datos reflejadas, el rendimiento disminuirá en las bases
de datos principales. SQL Server 2008 ayuda a mejorar una parte de esta carga mediante la compresión
de secuencias de registro.
El siguiente aspecto más importante a tener en cuenta en la creación de reflejos es la memoria y los
requisitos de los subprocesos. Todas las bases de datos reflejadas ocupan un subproceso además de
memoria. Si un servidor de baja potencia tiene una muchas bases de datos reflejadas, esto puede
suponer una carga excesiva para el servidor al combinarlas con la carga de trabajo habitual.

Además, debe tener en cuenta cómo llevará a cabo la creación de reflejos de bases de datos. En el modo
sincrónico, las transacciones de la base de datos principal no se pueden confirmar hasta que todos los
registros de transacciones se hayan copiado en el registro de transacciones de la base de datos
reflejada. Por lo tanto, cualquier retraso causado por una red sobrecargada podría provocar un
problema de rendimiento de la carga de trabajo de la principal.

En el modo asincrónico, las transacciones se pueden confirmar en la principal sin tener que esperar,
aunque un retraso de la red podría aumentar el número de registros de transacciones en espera de
envío. Esto puede causar problemas relacionados con el tamaño del registro de transacciones. O, lo que
es peor, los registros de transacciones que no se hayan enviado se perderán en caso de error. Por lo
tanto, cuantos más registros de transacciones queden sin enviar, mayor será la probabilidad de perder
datos en una situación de recuperación.

Las situaciones pueden ser muy diferentes y he detectado algunos ejemplos interesantes en entornos de
producción reales. Por ejemplo, advertí un entorno con 150 bases de datos con una actividad muy
pequeña y sin sincronización. Las 150 bases de datos se reflejaron sin problemas.

Por el contrario, también pude ver una configuración que solamente tenía tres bases de datos muy
cargadas sin una conexión de red buena. En esa situación, apenas se pudo reflejar una base de datos
antes de que la falta de ancho de banda de la red degradara la carga de trabajo.

La clave del éxito es, en primer lugar, realizar el cálculo de generación de registros. Si parece que el
ancho de banda de red disponible puede ser compatible con el número de las bases de datos que desea
reflejar, no debería haber ningún problema. Pruebe su configuración antes de ponerlo en ejecución y
asegúrese de incluir todas operaciones que podrían generar un registro de transacciones (especialmente
todo el mantenimiento de bases de datos que pueda realizar).
Paul S. Randal es el director general de SQLskills.com y uno de los profesionales más valorados (MVP)
de SQL Server. Trabajó en el equipo del motor de almacenamiento de SQL Server de Microsoft de 1999 a
2007. Paul escribió las directrices de reparación de DBCC CHECKDB para SQL Server 2005 y fue
responsable del motor de almacenamiento del núcleo durante el desarrollo de SQL Server 2008. Es
experto en recuperación de desastres, en alta disponibilidad y en el mantenimiento de bases de datos,
además de moderador habitual en congresos. Además, es autor de un blog: SQLskills.com/blogs/paul.

© 2008 Microsoft Corporation and CMP Media, LLC. Reservados todos los derechos. Queda prohibida la
reproducción parcial o total sin previa autorización.

También podría gustarte