Seguimos con nuestra serie de índices en SQL Server y vamos a profundizar en la estructura de las tablas que vimos ayer. Además vamos a introducir conceptos nuevos como las particiones y las tablas HEAP. Antes de continuar, si aún no lo habéis hecho, os recomiendo leer la primera entrega de esta serie de índices donde hicimos una introducción y aclaramos los conceptos básicos sobre los que vamos a profundizar ahora.
Estructura física de las tablas
Como vimos en la introducción las tablas son en realidad la representación de los datos almacenados en páginas de 8Kb de información. Pero por encima de estas páginas tenemos una estructura lógica que indica dónde se ubican los datos. Del mismo modo, podemos definir particiones, que son divisiones horizontales físicas en función de los valores de una columna.

Como podéis ver en la imagen nuestra tabla, tenga o no particiones, sea HEAP o tenga un índice clustered se compone de páginas del tipo IN_ROW_DATA, LOB_DATA y ROW_OVERFLOW_DATA.
IN_ROW_DATA almacena la mayoría de la información de nuestras filas. Hay tipos de datos especiales que por su gran tamaño no caben en las páginas de datos y se almacenan en LOB_DATA. Por último, cuando definimos una columna que de longitud variable se almacenará en IN_ROW_DATA siempre que sea posible y cuando por tamaño no se pueda irá a una página tipo ROW_OVERFLOW_DATA.
Tablas HEAP
Como vimos, cuando escribimos en una tabla HEAP los datos se escribirán en el primer hueco libre en las páginas ya asignadas. Si no hay hueco disponible se creará una nueva página. Además se asignará un identificador único a cada fila conocido como RID. Aunque no existan índices, SQL necesita localizar donde se encuentran las páginas de una tabla HEAP y para ello hace uso de un IAM o mapa de asignación de índices. El IAM almacena la ubicación de las páginas que componen la tabla pero, no identifica de ninguna manera los RID. Para buscar una fila SQL Server irá al IAM y recorrerá secuencialmente todos los registros de todas las páginas enlazadas al IAM. Como podéis adivinar, esto no es nada bueno en términos de rendimiento, sin embargo no es el peor de los problemas de las tablas HEAP.
Redirección de Punteros
Cuando se modifica un registro de una tabla HEAP es posible que la nueva información no quepa en el espacio que tenía asignada esa fila. En este caso, no se mueve toda la fila a una nueva ubicación sino que ese registro se escribe en otro sitio y en su ubicación original se deja un puntero hacia la nueva ubicación.
Esto complica mucho la lectura, pues para buscar una fila, SQL Server leerá la primera página del IAM que le dirá donde está la primera página de datos. Leerá secuencialmente toda la página de datos hasta que se encuentre termine, irá al IAM a buscar las siguientes páginas y hará lo mismo. Cuando termine con las páginas de datos referenciadas en la primera página del IAM irá a la siguiente página del IAM y habrá lo mismo. Así todas las veces que sea necesario hasta leer completamente la tabla. Por el camino se encontrará punteros que apuntan a páginas LOB, Overflow o simplemente a otras páginas con datos que se han actualizado y no cabían en la ubicación original.
Si esto os parece un problema pensad en los discos duros mecánicos donde una aguja se va moviendo físicamente para posicionarse en la posición correcta del disco y así leer los datos. Una locura, ¿verdad? Es mejor tener nuestras tablas ordenadas y para eso vamos a usar los índices clustered. Pero esto lo veremos en profundidad en el próximo artículo, mientras, podéis dejarme vuestras dudas y comentarios abajo, por Twitter o mail.
Contenido de la serie
Introducción a los índices en SQL Server (Índices parte 1)
Índices Clustered y Primary Keys (Índices parte 3)
Índices Nonclustered (Índices parte 4)


[…] entender lo que vamos a ver tenemos que tener claro de antemano lo que vimos en la primera y la segunda entrada de esta serie. Si aún no lo has leído es el momento, para aquí mismo y vuelve cuando lo […]
[…] nuestra serie de Índices en SQL Server. Después de una introducción y de profundizar en las tablas HEAP y los índices clustered ha llegado el turno de los índices nonclustered. Durante este blog vamos […]
[…] Estructura física de las tablas y HEAP (Índices parte 2) […]
[…] Estructura física de las tablas y HEAP (Índices parte 2) […]
[…] Estructura física de las tablas y HEAP (Índices parte 2) […]
Hola, enhorabuena por el blog, es impresionante lo bien explicado que está y lo necesario de este tipo de información.
Una duda, ¿sigue siendo una recomendación establecer el tamaño de bloque en 64kb en aquellas unidades que alberguen las bases de datos y logs?
Hola Carlos,
Primero de todo gracias por el feedback y las buenas palabras. Me alegro mucho que os parezca útil lo que comparto por aquí.
Ahora ya respondiendo a tu pregunta la respuesta es DEPENDE. Me parece una pregunta muy acertada, en muchas ocasiones encontramos consejos de configuración que se pusieron en su día en un manual de buenas prácticas y se han ido replicando a lo largo de los años sin tener en cuenta el avance del hardware. Por esto mismo tenemos que entender por qué cambiamos los valores y que afectación tiene. Sabiendo que SQL Server trabaja con páginas de 8Kbs lo que parece claro es que el tamaño de bloque debe ser igual o mayor a esa cifra. Ahora bien, ¿Cuánto mayor?. A mayor tamaño de bloque mayor rendimiento teórico pero corremos el riesgo de mayor fragmentación de los datos, mayor consumo de memoria y CPU para mover esos datos y mayor consumo de red. Con el estado actual de hardware nos podríamos plantear aumentar ese tamaño por encima de los 64Kbs sobre todo en entornos OLAP con grandes transacciones. Para entornos OLTP con muchas transacciones pero de pequeño tamaño, con 64Kbs el rendimiento es correcto por norma general.
Después de todo este tocho te lo resumo en una palabra: PRUEBALO. Es lo mejor que puedes hacer, probar en tu entorno de test como responde tu sistema con todas sus particularidades y valorar el cambio.
Un saludo y muchas gracias de nuevo por tu comentario.
[…] que tengan un índice clustered, el tipo de índice 0 está excluido de los filtros. Las tablas HEAP (sin índice clustered) necesitan otro tipo de tratamiento. Podemos ver también el filtro para […]
[…] recordáis, cuando hablamos de las estructuras físicas de los datos, os conté que SQL Server almacena los registros en páginas de 8 Kbs. El tamaño de la página en […]