Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Desde que hace unos pocos años Microsoft comenzó su paulatina conquista del mercado cor-
porativo con su producto abanderado Windows NT, era de suponer que si lograba una situa-
ción de preeminencia en el mismo ésta debía pasar por la labor de prestigiar su producto para
la gestión de bases de datos; estamos hablando de SQL Server.
En su origen el SQL Server de Microsoft parte del SQL Server de Sybase. Sin embargo, tras la
adquisición del mismo por parte de Microsoft ambos productos, aún conservando muchas co-
sas comunes, han ido separándose poco a poco. Acorde con esta situación, el primer SQL
Server de Microsoft –tal como el de Sybase- era multiplataforma (existían versiones para DOS,
Windows, Novell y OS/2), pero con el paso del tiempo el producto de Microsoft fue ciñéndose al
sistema operativo de su propietario, Windows NT abandonando las otras versiones, mientras
que el de Sybase ha continuado claramente dentro de la línea multiplataforma.
Esto ha marcado con claridad el perfil de SQL Server. Hoy es, quizá, el único producto de base
de datos basado en la tecnología multisubproceso (multithreading) de NT por contraposición a
la arquitectura multiproceso de la que participan la mayoría de los productos de su competen-
cia. ¿Qué virtud supone esto para SQL Server? Pues es bien sencillo, se trata de que, por la
razón mencionada, SQL Server es el producto que mejor se acomoda a la mecánica de trabajo
de Windows NT y, por tanto, con el que mejor resultado podemos obtener.
Por otro lado, SQL Server se ha hecho muy popular entre los desarrolladores de software. Su
buen entronque con los productos de desarrollo de Microsoft, Visual Basic y Visual C++, ha
hecho que existan muchas aplicaciones desarrolladas para este entorno a través de la tecnolo-
gía cliente/servidor.
Sin embargo, muchos de los desarrolladores que trabajan con el producto tienen un conoci-
miento muy superficial del mismo. SQL Server, como la mayoría de los productos de bases de
datos, trata de cumplir con los estándares que para SQL existen y, por tanto, sin tener un pro-
fundo conocimiento de su mecánica de almacenamiento de datos, nos podemos permitir tra-
bajar con él sin grandes riesgos. No obstante, conforme las aplicaciones van enfrentándose a
situaciones más complejas respecto a los datos, se nos hace necesario conocer con más pro-
fusión los caminos a seguir para optimizar recursos.
1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
datos que contienen tablas, índices y otros objetos. Por último, las tablas se dividen en filas y
éstas en columnas. Esto no es realmente así, o no lo es del todo. Efectivamente, en SQL Ser-
ver la unidad básica de almacenamiento de datos es la base de datos. Sin embargo las bases
de datos no son dispositivos físicos sino lógicos, como tales se encuentran contenidas en lo
que denominamos Database Device; éstos sí son realmente dispositivos físicos. El lector pue-
de comprobar que cada Database Device definido para SQL Server se corresponde con un
archivo en disco que se ubica en el directorio \mssql\data de la instalación de SQL Server. Los
Database Device sirven para almacenar las distintas bases de datos y cada base de datos
contiene distintas tablas e índices. No obstante, insistimos, los conceptos de base de datos,
tabla e índice son lógicos y no físicos.
La noción de página
La unidad real de almacenamiento físico dentro de un Database Device es lo que se denomina
la página. Toda la información en SQL Server se almacena en páginas de 2 KB. Cada página
tiene 32 bytes de cabecera conteniendo:
Las páginas se agrupan en grupos de 256 páginas contiguas en lo que se denomina una Allo-
cation Page. Cada una de estas unidades tiene una primera página que realiza las funciones
de índice del resto de las páginas contenidas en la misma. Dentro de estas unidades, las pági-
nas se colocan en bloques contiguos de 8 páginas. Esto es lo que se denomina extent. En una
unidad de asignación hay, por tanto, 32 extent. Al crear una tabla, ésta toma como tamaño
mínimo (aunque no tenga ninguna fila, un extent o lo que es lo mismo, 16 KB.
Qué es un extent
Un extent es un bloque de 8 páginas contiguas. Cada extent mide, por
tanto, 16 KB. Este es, asimismo, el tamaño mínimo que una tabla, aun-
que no tenga ninguna fila, puede tener.
2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Por último, hay que reseñar que cada página puede contener como máximo 256 filas de
datos.
Por tanto, la imagen que debemos hacernos de cómo se almacenan físicamente los datos
en SQL Server es la de una cadena de páginas contenedoras de filas, tal que en cada una
de ellas hay referencias a la anterior y las posterior de forma que la secuencia real de los
datos sea fácilmente perseguible. Para su mejor ubicación estas páginas se agrupan en
extents y éstos en allocation pages.
Cada vez que una consulta nuestra requiere leer una fila, el sistema, a través de las es-
tructuras de índices necesarias, localiza la página donde se halla esa fila la carga en me-
moria y nos devuelve los valores requeridos. Igualmente, cuando estamos actualizando
información en la base de datos, las páginas se actualizan de forma se van llenando de fi-
las y dividiendo en páginas nuevas según el sistema lo va requiriendo.
Obviamente, de esta manera de organizar las cosas sacaremos muchas lecciones para
optimizar el tratamiento de los datos en SQL Server. Pero demos tiempo al tiempo.
Normalmente, el diseñador de la base de datos se ocupa en primer término de definir las tablas
con sus correspondientes columnas y las claves primarias y ajenas para cada una de ellas. La
mayoría de los sistemas (y esto incluye a SQL Server) poseen una mecánica automática de
creación de índices en el mismo momento que una de estas claves ha sido definida.
Sin embargo, la mayoría de las veces, esta mecánica queda pobre. Si queremos establecer
mejores y más rápidos sistemas para acceder a los datos es bastante conveniente que conoz-
camos la mecánica de manejo de índices que cada sistema realiza y que hagamos manual-
mente cuantas aportaciones sean necesarias a esa creación automática aportada por el siste-
ma.
Sentado esto nos queda por determinar, pues, cómo son los índices en SQL Server, cómo
podemos trabajar con ellos y cuales son más adecuados para cada tipo de trabajo.
Los índices en SQL Server son índices B-Tree totalmente similares en su concepción y estruc-
tura a los de cualquier otro producto similar. Estos índices poseen una estructura de árbol de
modo que los datos en ellos se depositan en hojas accesibles a través de una organización de
ramas. Un árbol B-Tree normalmente posee una root page o página raíz donde se encuentra,
por así decirlo el índice principal del árbol. Cada línea de dicha página apunta a otra página
conteniendo otros índices secundarios (node pages) que sirven para acceder más rápidamente
a los datos. Desde estos índices secundarios podemos ir a otros índices secundarios o ya di-
rectamente a las hojas (leaf pages) del árbol donde se contiene la referencia a la información
que estamos buscando.
Veamos un hipotético sistema de ejemplo. Tenemos una tabla de clientes que contiene 100
filas con datos de 100 clientes distintos. Si no usamos ningún sistema de indexación, cuando
deseamos acceder, por ejemplo, al cliente 78, tenemos que procesar secuencialmente la tabla
y recorrerla fila a fila hasta llegar al cliente que necesitamos. Contando con que los datos estu-
1
Las reglas de Codd junto con un monumental conjunto de excelente material sobre teoría de
bases de datos puede verse en Concepción y Diseño de Bases de Datos, Adoración de Mi-
guel y Mario Piattini, editorial RA-MA, Madrid, 1992.
3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
vieran ubicados en orden en la tabla necesitaríamos 78 accesos hasta que se cumpliera la
condición de que el valor que buscamos (78) se corresponde con el código de cliente examina-
do. Pero, pensemos ahora en una técnica que nos ayude a conseguir esto mismo, pero con
menos accesos. Supongamos que podemos montar un sistema de indexación B-Tree y que
nuestro sistema permite que cada hoja del árbol pueda contener hasta un máximo de 5 filas.
Podíamos montar la lógica de nuestros datos del siguiente modo: primero una página raíz
contenido un índice de donde se encuentran realmente los datos. Por ejemplo:
1 Node page 1
21 Node page 2
41 Node page 3
61 Node page 4
81 Node page 5
Root page
El lector verá que lo que hemos hecho ha sido partir la totalidad de las 100 filas en 5 porciones
(el espacio que hemos definido para nuestra página B-Tree teórica). La primera fila de esta
página nos servirá si deseamos localizar un cliente comprendido entre el 1 y el 20, la segunda
entre el 21 y el 41 y así sucesivamente.
Veamos ahora como serían cada una de esas node pages 1 a 5, por ejemplo la 1.
Como puede verse ahora hacemos lo mismo, es decir, las 20 filas contenidas en la primera
entrada de la root page las volvemos a dividir en bloques de 5 filas, de modo que ahora la pri-
mera entrada de la tabla nos servirá para localizar clientes cuyo código esté comprendido entre
el 1 y el 4, la segunda entre el 5 y el 8 y así sucesivamente.
Veamos cómo sería la página 4 (de las reseñadas en el raíz) ya que dicha página es la que
vamos a necesitar para localizar el cliente 73 del que antes hemos hablado.
Veamos, por último, como sería la Leaf page 4.4, ya que ésta es la que nos servirá para ubicar
al cliente que buscamos.
73 Data page xx
74 Data page xx
75 Data page xx
76 Data page xx
Leaf page 4.4
4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
¿Cuántos accesos necesitamos ahora con este sistema para localizar al cliente 73? Pues bien,
primero cargaríamos la root page y necesitaríamos 5 accesos para saber que el dato está refe-
renciado en la node page 4. Cargamos dicha página y necesitamos 5 accesos más para saber
que el dato está referenciado en la leaf page 4.4. Cargamos dicha página y con 1 sólo acceso a
la misma ya sabemos que el cliente se encuentra en la Data Page xx (esta es ya una página de
datos de una tabla y no de un índice), así, pues, con un acceso más para llegar a esa página
habremos terminado nuestra búsqueda. En total hemos necesitado 12 accesos cuando antes
necesitamos 73. En un sistema pequeño como este (100 filas) la diferencia es notoria, pero una
tabla con centeneres de miles o millones de filas la diferencia es abismal.
Ni que decir tiene que aquí hemos pensado, para que sirva de ejemplo, un sistema absoluta-
mente sencillo que se caracteriza, además, por tener sólo uno nivel de node pages. No obs-
tante, cuanto más grande es un índice existen más páginas de nodo que hacen referencia a
otras páginas de nodo, y así sucesivamente, de forma que el tratamiento es más lento al nece-
sitarse más accesos.
1. Los índices nos ayudan a localizar los datos con mucha rapidez, por tanto cuando necesi-
tamos que nuestras aplicaciones hagan selecciones de forma rápida lo mejor es que ten-
gamos una buena estructura de índices diseñada.
2. La labor de mantenimiento de un índice es compleja. El gestor de bases de datos ha de
mantener no sólo la información contenida en las tablas sino también la contenida en los
índices, por tanto cada actualización a la base de datos se hace más lenta. Fíjese el lector
que la forma más rápida de insertar datos en una tabla es cuando ésta no posee ningún ín-
dice. Los datos se van añadiendo en la forma de páginas antes reseñada, por el final de las
que ya existan asociadas a la tabla. Si hay hueco en las páginas existentes, las filas se
añaden ahí y si no lo hay se crean nuevas páginas. Cuando existe un índice, además de
hacer lo anterior hay que proceder a actualizar la estructura de árbol del índice, Si la fila in-
sertada cabe en la leaf page donde le corresponda estar, el tema es más o menos rápido,
pero si esto no es así, el sistema ha de andar partiendo páginas existentes en dos de forma
que el dato pueda ser incorporado en los espacios libres que queden en las dos nuevas
páginas productos de la partición de una llena. Asimismo, han de actualizarse las referen-
cias en las node pages y root page si procede.
3. En cualquier caso, hay que tratar que los niveles de profundidad de las node pages sean
los menores posibles de forma que los accesos sean más rápidos. Esto podemos conse-
guirlo tanto a nivel lógico, definiendo claves lo más cortas posibles, como a través de las
herramientas informativas que SQL Server nos proporciona y que luego veremos.
5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Consejos y trucos
Si nuestra aplicación es de tipo transaccional (es decir que para ella son
críticas las actualizaciones) lo mejor es que reduzcamos los índices al
menor número posible, ya que de este modo las actualizaciones irán
mucho más rápidas. Sin embargo, si lo más crítico para nuestra aplica-
ción son las consultas, lo mejor es que nuestra estructura de índices esté
altamente estudiada y sea altamente compleja de forma que cubra todos
los casos de selección posibles.
Pero ¿cómo aunar ambos criterios en aplicaciones híbridas? Bueno,
pues, siempre hay un justo término medio que cada diseñador de BD ha
de saber evaluar. Si esto no es posible quizá una buena táctica sea dis-
poner de dos bases de datos, una para las transacciones y otra para las
consultas. La segunda se actualiza, por ejemplo, cada noche a través de
un proceso automático y, se diferencia de la primera, en que contiene
una estructura de índices mucho más compleja.
La diferencia entre ambos tipos de índice se muestra de forma comparada en las figuras 1 y 2.
6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Figura 1
Figura 2
7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Para mantener la estructura de un índice clustered SQL Server necesita mantener siempre
ordenados en función de la clave de dicho índice, los datos presentes en la tabla. En tanto que
una tabla sólo puede contener los datos de una única forma, sólo es posible mantener un único
índice clustered por tabla, mientras que índices non-clustered pueden mantenerse tantos como
se deseen. Debido a todo esto los índices clustered nos permiten siempre más rapidez en el
acceso a los datos, pero también son más costosos de mantener en tanto que necesitan
mantener siempre una versión ordenada de los datos presentes en la tabla.
De todo lo visto se deduce lo importante que es el proceso de seleccionar qué tipo de índice
deseamos para las distintas columnas de nuestra base de datos. No es menos importante, el
seguimiento posterior del rendimiento del índice. SQL Server nos da alguna información im-
portante a este respecto. Por ejemplo, veamos en la figura 3 algunos datos de un índice non-
clustered. A esta información accedemos pulsando el botón derecho del ratón sobre la tabla
correspondiente y seleccionando Indexes.
Como puede verse en la información presente en la ventana se nos informa que el índice ocu-
pa 1032 KB. Igualmente se nos indica que el índice se creó con un factor de relleno de 0 (más
tarde explicaremos este concepto). Asimismo se nos dan unos valores mínimos, medios y má-
ximos muy importantes, se trata de:
Si reconstruimos el índice para convertirlo en clustered el lector notará como cambian los valo-
res que ahora pueden verse en la figura 4.
8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Figura 4: Datos de un índice clustered
El lector notará la diferencia inmediata en las cifras. Ahora sólo tenemos dos niveles (lógica-
mente ahora no existen leaf pages). Como consecuencia de esto el tamaño del índice ha baja-
do considerablemente (de 1032 KB a 16 KB).
No obstante, hay que tener en cuenta que si en una tabla borramos muchas filas, pero inserta-
mos pocas el espacio libre que va quedando en las data pages no se recupera en su totalidad.
Esto puede causar pérdida de rendimiento y, por tanto, es aconsejable que reorganicemos las
2
tablas de vez en cuando .
2
No es el objetivo de esta conferencia presentar aspectos sintácticos, por tanto no abordare-
mos aquí en profundidad los mandatos y opciones que tenemos para realizar estas tareas. No
obstante, recomendamos al lector que revise en la ayuda de Transact SQL, el ítem DBCC, ya
que es con dicho mandato con el que habitualmente reorganizamos las estructura de una base
de datos.
9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Consejos y trucos
Si queremos recuperar de forma automática el espacio que va quedando
en las páginas de datos conforme borramos filas dentro de una tabla, es
conveniente que dicha tabla tenga un índice clustered.
Un factor de relleno con valor 0 indica que las páginas de hoja en los índices non-clustered o
las de datos en los clustered estarán totalmente llenas, pero que habrá espacio (al menos una
fila) en las intermedias para ampliar el índice sin demasiado coste. En cambio, un fill factor de
100 deja totalmente completas todas las páginas lo que lo hace adecuado para sistemas total-
mente estáticos. Un factor de relleno con valor de 50 nos da una situación de equilibrio en las
páginas que puede ser valorable como estándar para aplicaciones no críticas en cuanto tiempo
de respuesta ni en las inserciones ni en las queries.
Consejos y trucos
Si queremos un sistema muy rápido en la selección de datos, lo mejor es
usar un índice clustered con un factor de relleno de 100. Si embargo,
este será el sistema más lento posible en las actualizaciones.
En versiones anteriores de SQL Server el factor de relleno afecta sólo a las leaf pages o a las
data pages. A partir de la versión 6.5 también pueden verse afectadas las node pages y la root
page. Para ello hemos de usar la cláusula pad_index del mandato CREATE INDEX.
La labor que más enlentece la inserción de datos es la de la división de páginas que se produ-
ce para mantener de forma automatizada una estructura B-Tree. Como ya hemos dicho antes,
cuando las páginas se van llenando es necesario dividirlas en dos de forma que quede espacio
libre en ellas para albergar nuevos valores. Esta continua división de páginas puede ser total-
mente perjudicial para la rapidez en la actualización. Si esto se produce es conveniente que
revisemos nuestra estrategia de índices y la cambiemos por otra donde se produzcan menos
divisiones de páginas.
Consejos y trucos
La división de páginas de un índice es una operación que queda regis-
trada en el log de transacciones de cada base de datos. Si queremos
monitorizar el datos, podemos ejecutar la siguiente SELECT:
SELECT Count(*) from syslogs where op=16
10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Como ejercicio recomendamos al lector que cargue la página de propiedades de un índice
(botón derecho del ratón sobre la tabla y elegir Indexes –claro dentro del SQL Enterprise Ma-
nager-) tal como puede verse en la figura 5 y modifique el Fill Factor que aparece en ella para
cualquier de sus índices. No es necesario que reconstruya el índice cada vez que cambie en
esta pantalla el Fill Factor ya que el sistema recalcula de forma inmediata el impacto que cada
cambio tendrá en el tamaño del índice, en los niveles del árbol y en las filas por cada tipo de
página. Verá consecuencias interesantes, como que si anota 0 ó 50 los datos reflejados serán
muy similares, pero si se fija en la diferencia entre 1 y 100 verá que es impactante. Un valor de
1 hace subir las cifras de filas por página de modo increíble, ya que esta es la fórmula con la
que más páginas casi vacías se crean. Un valor de 100 deja el tamaño superajustado, ya que
si lo usamos se crearán tantas páginas como necesitemos para dar cobertura a los valores
actuales sin desperdiciar ni una gota de espacio libre en las páginas del índice.
11
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
b. Las columnas donde se vayan a hacer selecciones entre un rango amplio
c. Las columnas sobre las que se van a hacer JOIN
d. Las columnas sobre las que se vaya a hacer ORDER BY
En general, todo este tipo de operaciones son más pesadas que las de seleccionar un
caso en una clave primaria, de forma que no siempre la elección de un índice clustered
para la clave primaria es la más acertada.
Consejos y trucos
En general, y a pesar de cualquier norma enunciada hasta ahora lo me-
jor es que para afinar totalmente un sistema probemos con él distintas
alternativas de indexación y finalmente seleccionemos la que nos parez-
ca más adecuada. Para esto SQL nos da la importante ventaja de que
las tablas pueden diseñarse prácticamente sin ningún índice, o con de-
terminados índices, pero que cualquiera de estos contextos es fácilmente
cambiable sin tocar el código fuente de las aplicaciones que corren con-
tra la base de datos de la que estudiamos sus índices.
Imaginemos, por ejemplo, que tenemos una tabla de cabecera de facturas que tiene 5.000 filas,
cada una con un valor único que es el número de factura. Igualmente, tenemos otra tabla con
las líneas de la factura. Esta tabla tiene 52.000 filas. Esta segunda tabla tiene un índice por el
número de factura. Lógicamente, en dicho índice los valores únicos serán 5.000, ya que esas
son las facturas que existen. La densidad de ese índice será 1/5.000, o lo que es lo mismo
0.0002. Por tanto, la media de valores duplicados será: 52.000 * 0.0002 = 10.4, o lo que es lo
mismo, cada factura tiene una media de 10,4 líneas.
Saber la densidad de un índice puede interesarnos a fin de calcular lo pesada que será la res-
puesta de una consulta debido al excesivo número de claves duplicadas presentes en la mis-
ma.
Si deseamos conocer el dato de la densidad de nuestros índices junto con cualquier otro de
interés al respecto de los mismos podemos usar:
El Index Covering
Por Index Covering se conoce la técnica por la cual cuando en un índice non-clustered se pre-
gunta en la SELECT sólo por un campo que es parte del índice, la SELECT se resuelve sólo
con las leaf pages del índice sin llegar a las páginas de datos.
12
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Por ejemplo, pensemos en una tabla de alumnos que tiene un índice non-clustered por el nom-
bre del alumno y analicemos la siguiente SELECT:
Esta consulta nos mostraría todos los alumnos cuyo nombre comienza por la letra A y que vi-
ven en Madrid. SQL Server habrá empleado para resolverla la técnica del Index Covering, ya
que el dato que se pide mostrar en la SELECT es sólo el nombre del alumno y dicho dato se
encuentra en las leaf pages del índice, por lo que no necesita ir a buscarlo a la tabla corres-
pondiente. Sin embargo si nuestra SELECT fuera:
el asunto cambiaría notoriamente, ya que el dato de la ciudad no se encuentra en las Leaf Pa-
ges del índice y, por tanto, hay que ir a buscarlo a la tabla correspondiente.
Debido a esto es muy importante que siempre que sea posible usemos la técnica del Index
Covering, ya que hará mucho más rápidas nuestras consultas.
Consejos y trucos
Siempre que podamos es conveniente mostrar en la salida de la
SELECT el menor número de valores posible. Muchas veces empleamos
SELECT * sin que realmente necesitemos la totalidad de los valores de-
vueltos. Si restringimos lo devuelto por la SELECT a los valores presen-
tes en el índice non-clustered que se usará para resolverla, todo irá mu-
cho más rápido.
El optimizador de consultas
SQL Server posee una herramienta interna llamada el optimizador de consultas. Cada vez que
nosotros hacemos una SELECT dicha SELECT es analizada por el optimizador que es quien
decide finalmente los índices que se usarán para resolver la consulta en cuestión. El objetivo
perseguido por el optimizador es conseguir resolver la consulta con la mejor cifra de accesos
posibles.
13
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Dentro de estos pasos, lógicamente, el más importante es el de la optimización. Podemos divi-
dirlo en varias fases:
1. Análisis de la consulta
La página de distribución
En todo este proceso de optimización existe una herramientas muy importante para el optimi-
zador, se trata de lo que denominamos la página de distribución de cada índice. La página de
distribución es un recurso usado por el optimizador de consultas para conocer el número apro-
ximado de filas que concordarán con un argumento de búsqueda. Esta página es mantenida de
forma automática por el sistema, pero el administrador puede actualizarla a través de
Update Statistics
Hay que tener en cuenta que el optimizador sólo usa la página de distribución cuando en las
condiciones de búsqueda empleamos constantes. Por ejemplo, se usará con:
WHERE idcliente=5467
Y no se usará con
14
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
Figura 6: Una página de distribución
le supondrá leer del orden de 6.069 filas, ya que la fila 1.000 se encuentra en el paso 20 y la
fila 7.000 se encuentra en el paso 139. La diferencia entre ambos valores es 119. Dicha dife-
rencia multiplicada por el intervalo medio entre pasos (51) nos da la cifra mencionada.
La página de distribución es, pues, básica para el optimizador, ya que usándola puede saber el
número de filas previsto que devolverá la consulta.
Es muy importante que tengamos esto en cuenta, ya que la mayoría de las aplicaciones clien-
te/servidor están basadas en el uso intensivo de los procedimientos almacenados que luego
son ejecutados a requerimiento de la aplicación cliente. Si creamos nuestros procedimientos
15
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS
conteniendo SELECT con datos variables de cualquier tipo que luego son pasados en el mo-
mento de la ejecución, el plan para resolver la SELECT se creará con el primer juego de pará-
metros enviados al procedimiento y ya nunca se volverá a cambiar a no ser que usemos la
opción descrita.
Consejos y trucos
Si programamos procedimientos almacenados con SELECT que contie-
nen muchos datos variables que se pasan como parámetros en el proce-
dimiento, es conveniente usar la opción with recompile ya que si no el
plan generado por el optimizador estará basado en los parámetros usa-
dos la primera vez que se ejecute el procedimiento y no se volverá a
cambiar más. Esto puede ser nefasto para el rendimiento
WHERE Datepart(month,fecha) = 5
Debemos, por tanto, en nuestras WHERE evitar el uso de funciones que inhiban el uso de los
índices que ayudarán al optimizador a resolver la consulta de modo rápido.
Igual sucede con el uso de LIKE. Si usamos el siguiente patrón ‘A%’ se usará el índice, pero si
usamos ‘%A%’ no se usará, lógicamente, ya que en este segundo caso lo que pretendemos
localizar es una A en cualquier posición de la clave mientras que en el primero intentamos ha-
llar cualquier valor que comience por A. Lógicamente, las claves de índice en SQL Server
siempre comienzan a evaluarse comparando por los valores a la izquierda.
Conclusiones
En general no es cuestión de dar aquí un conglomerado enorme de consejos sobre qué usar
en las cláusulas WHERE u otro tipo de cosas similares. Quizá en otro momento y en otro lugar
amplie lo aquí escrito en esa dirección. Lo pretendido por esta conferencia es, más bien, acla-
rar cuestiones generales sobre la arquitectura de SQL Server, su funcionamiento y la repercu-
sión de determinados factores en aspectos de rendimiento.
16
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - © Grupo EIDOS