Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Datos
Subttulo: Estadsticas de uso de ndice
Dirigido a: Administradores de Bases de Datos
rea: Bases de Datos
Autor: Pablo F. Dueas Campo
Resumen
SQL Server 2005 nos ofrece unas consultas dinmicas nuevas que nos dan mucha
informacin sobre los ndices de una base de datos. Dichas consultas son aprovechadas
por los informes que nos ofrece usando la herramienta Reporting Services. Al usar
directamente las consultas, no vamos a obtener unos informes tan bonitos, pero s
tendremos mayor control sobre los datos que se muestran, aparte de poder obtener algn
que otro extra.
Introduccin
ndices
El primer reto es conseguir todos los ndices de la base de datos a la que estamos
conectados. Para ello usaremos la vista de sistema sys.indexes. Si la consultamos
directamente veremos que nos va a dar ms ndices de los que queremos examinar por
dos razones:
Da los ndices incluso de las tablas del sistema. Para filtrarlas vamos a usar una
propiedad extendida de los objetos que indica si es una tabla de usuario o de
sistema. Como los ndices se relacionan con la tabla a que pertenecen
directamente mediante el campo object_id, no hace falta nada ms para aplicar
el filtro: ObjectProperty(I.[object_id], 'IsUserTable') = 1.
Tambin da los ndices de tipo montn, que en realidad no son tales, sino la
localizacin de las pginas de cada tabla. Por lo tanto, los filtramos tambin:
I.[type] <> 0.
De esta vista vamos a necesitar algunos campos que son importantes para el anlisis
posterior de los datos. El ms obvio es el nombre del ndice. Luego el que quizs sea el
En el presente artculo vamos a analizar a fondo la nueva consulta dinmica que nos
ofrece los datos de uso de los ndices. Mediante los nmeros que nos d, podremos
evaluar si tenemos demasiados ndices, si algunos no se estn usando y por lo tanto se
pueden borrar o si es ms costoso mantenerlos que el beneficio que dan. Al final se
presenta la consulta que vamos a ir desglosando y que nos ofrece todos los datos sobre
el uso de los ndices.
ms importante, pues nos dice el tipo de ndice que estamos viendo y, sobre todo, si es
agrupado. Esto va a incidir en su uso, dado que un ndice agrupado no es otra cosa que
la tabla ordenada, amn del ndice, por lo que habr un dato adicional como son los
lookups que se realizan en ellos. Tambin es importante saber si el ndice es nico,
pues aunque no se use y cueste su mantenimiento, son imprescindibles para obligar a
que se cumpla dicha restriccin. Por ltimo, he aadido si el ndice es hipottico o no,
aunque no le daremos uso por ahora.
Esquema y Tablas
A continuacin es importante obtener el esquema y la tabla a la que pertenece el ndice.
Como hemos manifestado, el campo Object_Id nos dice el identificador de la tabla a la
que pertenece. Una vez que tenemos la tabla, mediante el identificador del esquema,
podemos obtenerlo. As incluimos los tres campos que identifican al ndice dentro de la
base de datos que estamos analizando.
De estos tres datos vamos a obtener otros dos adicionales. El primero es que vamos a
numerar las tablas para una distincin adicional de cada una de ellas y para que as nos
sea ms fcil encontrarlas. Para ello usamos la funcin Dense_Rank que nos devuelve la
posicin de cada fila dentro de la ordenacin que le pasamos. No usamos la funcin
Rank, como en el dato siguiente, porque queremos que la numeracin no tenga saltos.
La siguiente columna nos numera los ndices dentro de cada tabla. Para ello usamos la
posicin de cada fila dentro del esquema, tabla e ndice, que nos va a dar una
numeracin seguida (sin saltos) porque estos tres campos identifican unvocamente cada
fila. Se hace una particin en cada esquema y tabla para lograr nuestro objetivo.
La vista dinmica muestra la informacin que se lleva sobre el uso de ndices. Devuelve
los datos de una cach dentro de SQL Server que no se guarda en disco. Es decir, est
vaca cada ver que una instancia de servidor comienza y se pierden cada vez que es
cerrada. Por lo tanto, se guarda informacin sobre el uso de ndices slo desde que se
abri la base de datos a la que pertenecen. Adems, slo se guarda informacin de
aquellos ndices que se usan, por lo que puede haber ndices en sys.indexes que no
aparezcan en sys.dm_db_index_usage_stats.
De lo anteriormente dicho, deducimos que la unin con las tablas ya relacionadas debe
ser un LEFT JOIN. Adems, esta vista nos ofrece datos de todos los ndices de la
instancia, por lo que debemos restringirla a la base de datos a la que estamos conectados
para que no nos traiga algn dato que pueda tener de otra: U.[database_id] =
(SELECT db_id()).
Como se puede apreciar en la consulta, aquellos ndices que no aparezcan con datos, son
los que no se han usado desde que se inici la instancia de SQL Server. Por lo tanto, se
pueden eliminar? Depende. Los ndices no agrupados que sobran, restan velocidad de
varias maneras:
Cada vez que un rcord es insertado en su tabla, hay que insertar otro tambin en
el ndice. Esto es actividad de E/S adicional, sobre todo si se divide una pgina
porque ya no caben ms entradas. Adems, hay que mantener el rbol
balanceado.
Estadsticas de uso
Cada vez que se borra un rcord de su tabla, hay que borrar otro del ndice.
Aunque esto no es tan costoso, es actividad del procesador y de E/S adicional.
Cada vez que se actualiza una fila, la tabla tiene un ndice agrupado y alguno de
los valores de la clave cambia (cosa que no debera hacerse), hay que actualizar
la entrada correspondiente en el ndice.
Como vemos, bastante actividad adicional para mantener los ndices. Sin embargo,
afirmamos que depende, que no siempre hay que eliminarlos. Por eso incluimos las
columnas adicionales de sys.indexes, porque un ndice agrupado, una clave primaria, un
ndice nico o una clave externa cumplen misiones que justifican su existencia ms all
de que cmo se usen en las consultas.
Funcionamiento de la cach
Cada bsqueda, recorrido, vistazo o actualizacin en cualquiera de los ndices, bien sea
originado por una consulta de usuario o por el sistema (por ejemplo, para recabar
estadsticas), es contado como un uso de dicho ndice e incrementa su contador
correspondiente. En el caso de que an no haya una entrada, se crea con todos los datos
a cero, y se procede al incremento mencionado.
El contador de actualizaciones indica el mantenimiento del ndice causado por las
operaciones de insercin, actualizacin o borrado en la tabla o vista a la que pertenece,
y que afecten a dicho ndice.
Datos de la consulta
Si vemos las columnas que nos devuelve la consulta, aparecen dos grandes divisiones
entre la parte originada por consultas de usuario y la originada por consultas del
sistema. Ambas partes muestran la siguiente informacin por cada ndice:
El nmero de veces que un ndice ha sido usado para una operacin de bsqueda
(seek), tanto si es para una sola fila o si es para un recorrido ordenado. Es
decir, cuntas veces se ha usado el ndice como tal, llegando a las hojas a travs
de las ramas. Tambin da el da y hora de esta ltima operacin.
Ya hemos dicho que los contadores se vacan cada vez que se inicia el servicio de SQL
Server. Adems, cada vez que una base de datos es separada o puesta fuera de conexin,
tambin se vacan todos los contadores asociados con dicha base de datos.
ndice agrupado que nos ocupa suple el resto de los campos porque el primero
no cubra la consulta. Como los anteriores, lo complementa con el da y la hora
de la ltima operacin.
El nmero de veces que se tuvo que actualizar (update), sea por una insercin,
actualizacin o borrado. Tambin con el da y hora de la ltima operacin.
Beneficios
Seguidamente son los ndices que se usan muy poco. Hay que examinarlos para
ver si merece la pena mantenerlos. Por ejemplo, sirve para un informe que se
hace una vez al da, pero que se necesita que sea rpido. Se usa poco, pero es
necesario. En caso contrario, mejor eliminarlos.
Adems de que la consulta presenta ms datos que los informes de SQL Server, tambin
permite filtrados y ordenaciones. Por ejemplo, podemos querer ver slo los ndices que
no se han usado nunca, los que no se han usado desde determinada fecha, los que se han
usado poco, los pertenecientes a una tabla, incluso usar una frmula para evaluarlos
teniendo en cuenta la mayor utilidad de una bsqueda que la de un recorrido (como se
muestra comentado en la consulta) o correlacionando los usos del ndice son su
mantenimiento. Son formas ms rpidas de analizar los ndices que un informe
completo.
Conclusin
Las nuevas consultas dinmicas nos ofrecen una muy valiosa informacin sobre el
trabajo que hace SQL Server internamente. En concreto la
sys.dm_db_index_usage_stats nos es muy til para evaluar la conveniencia de
mantener, estudiar o eliminar un ndice. Hay que recordar que las optimaciones que
hace la base de datos son dinmicas y cambian en el tiempo. Usando esta consulta de
vez en cuando, podemos ver qu ndices han dejado de ser tiles o cules estn dando
ms trabajo mantenerlos que lo que ayudan en las consultas. Son, por tanto,
imprescindibles para el administrador de bases de datos y bienvenidas en SQL Server
2005.
SELECT
Dense_Rank() OVER (ORDER BY S.Name, T.Name) AS L1,
Rank() OVER (PARTITION BY S.Name, T.Name ORDER BY I.Name) AS L2,
S.Name AS [Esquema],
T.Name AS [Tabla],
I.Name AS [ndice],
CASE I.Type WHEN 1 THEN 'Agrupado' WHEN 2 THEN 'No agrupado'
WHEN 3 THEN 'XML'
END AS [Tipo de ndice],
CASE I.Is_Unique WHEN 1 THEN 'S' ELSE 'No' END AS [nico],
CASE I.Is_Hypothetical WHEN 1 THEN 'S' ELSE 'No' END AS
[Hipottico],
CASE WHEN U.User_Seeks IS NULL THEN '' ELSE Convert(VARCHAR,
U.User_Seeks)
END AS [Bsquedas de Usuario],
CASE WHEN U.User_Scans IS NULL THEN '' ELSE Convert(VARCHAR,
U.User_Scans)
END AS [Recorridos U],
CASE WHEN U.User_Lookups IS NULL THEN '' ELSE Convert(VARCHAR,
U.User_Lookups)
END AS [Lookups U],
CASE WHEN U.User_Updates IS NULL THEN '' ELSE Convert(VARCHAR,
U.User_Updates)
END AS [ActualizacionesU],
CASE WHEN U.Last_User_Seek IS NULL THEN '' ELSE Convert(VARCHAR,
U.Last_User_Seek, 113)
END AS [ltima Bsqueda de Usuario],
CASE WHEN U.Last_User_Scan IS NULL THEN '' ELSE Convert(VARCHAR,
U.Last_User_Scan, 113)
END AS [ltimo Recorrido U],
CASE WHEN U.Last_User_Lookup IS NULL THEN '' ELSE
Convert(VARCHAR, U.Last_User_Lookup, 113)
END AS [ltimo Lookup U],
CASE WHEN U.Last_User_Update IS NULL THEN '' ELSE
Convert(VARCHAR, U.Last_User_Update, 113)
END AS [ltima Actualizacin U],
CASE WHEN U.System_Seeks IS NULL THEN '' ELSE Convert(VARCHAR,
U.System_Seeks)
END AS [Bsquedas del Sistema],
CASE WHEN U.System_Scans IS NULL THEN '' ELSE Convert(VARCHAR,
U.System_Scans)
END AS [Recorridos S],
CASE WHEN U.system_Lookups IS NULL THEN '' ELSE Convert(VARCHAR,
U.System_Lookups)
END AS [Lookups S],
CASE WHEN U.System_Updates IS NULL THEN '' ELSE Convert(VARCHAR,
U.System_Updates)
END AS [Actualizaciones S],
CASE WHEN U.Last_System_Seek IS NULL THEN '' ELSE
Convert(VARCHAR, U.Last_System_Seek, 113)
END AS [ltima Bsqueda del Sistema S],
Apndice: Consulta