Grimpi IT Blog

enero 25, 2011

Lo nuevo de SQL Server 2011: COLUMN STORAGE INDEX

Filed under: Engine, SQL Server, SQL Server 2011 — grimpi @ 4:28 pm

Una de las características más importantes que promete SQL Server 2011, son los índices por columna.

Introducción
A partir del 2007, salieron a la luz distintas bases de datos llamadas “Column-oriented DBMS”, que implementaron el concepto de índice por columna, el cual prometía revolucionar el mercado, especialmente el de datawharehousing. Uno de los motores mas conocidos es Vertica (y su versión gratis, C-Store), también MonetDB, que es open source. Incluso Sybase lanzó un producto llamado Sybase IQ. Por supuesto, hubo otras empresas que lanzaron productos similares.
El problema de estos productos es que son “Column-oriented DBMS” exclusivamente. O sea, no almacenan la información de la misma manera que la almacena una típica base de datos relacional tradicional como Oracle, MySql o SQL Server. Esto significa que el mercado de estos productos está muy limitado a escenarios específicos.

Por el contrario, SQL Server 2011 promete ser la primera de bases de datos relacional “tradicional” en incorporar como una feature mas a su motor, el índice por columna, pudiendo ser combinado su uso con la tradicional estructura “row-store”.
 

¿Ahora bien, que es un índice por columna?
En todos los motores relacionales, los índices se almacenan por filas (rows). Esto significa que la estructura del índice en su última instancia, va a tener un puntero a un registro de una tabla. Existen distintas maneras de construir un índice (bitmap, b-tree, etc), pero todos estos métodos en definitiva hacen lo mismo: acelerar el acceso a un registro.
El índice por columna por el contrario, invierte la filosofía. Ya no busca registros, busca columnas. En una tabla “normal”, los registros son almacenados en páginas físicas de disco. Cada página contiene una determinada cantidad de registros (que varia según el motor y los registros. En SQL Server cada página de datos tiene un tamaño fijo de 8K). Un índice por columna, es al revés. En cada página de datos, se guardan columnas, no filas.

¿Bárbaro, ahora que ventajas tiene esto?
La respuesta es simple. Performance. Y por 2 razones.

1) Al estar las páginas de disco ordenadas por columnas, cuando hago una consulta, el motor puede leer solo las columnas que necesitamos para nuestra query, lo cual evita lecturas de disco innecesarias.
2) Es muchísimo mas probable que exista redundancia de información entre los valores de una misma columna en distintos registros, que entre los valores de las distintas columnas en un mismo registro, por lo tanto, es mucho mas fácil y eficiente la compresión de datos, lo que significaría mas información en memoria y menos acceso al disco. Ejemplo:
Si yo tengo 4 registros de 4 columnas cada uno:

  Col1 Col2 Col3 Col4
Row 1 01 Jose 01/01/2000 4
Row 2 02 Eduardo 02/02/2004 5
Row 3 03 Ramon 03/02/2004 5
Row 4 04 Susana 02/02/2004 5

Si yo comprimo esta información por columna, mi grado de compresión seria mucho mayor a que si yo comprimo por registro. Porque el grado de homogenización de valores dentro de una columna es mucho mayor. En cambio, en un registro, como tengo distintos tipos de datos y valores posibles entre ellos muy disímiles, la compresión no es tan efectiva. No es lo mismo comprimir 100 valores de un mismo tipo de datos, que comprimir 100 valores de distintos tipos de datos.
Por otro lado, existen diferentes técnicas de compresión que funcionan mejor con un tipo de datos que con otro (ejemplo: hay métodos que son más eficientes para números o binarios, y otros métodos que son más eficientes para texto). Por lo tanto, el motor elige una forma de compresión diferente dependiendo del tipo de dato de la columna, algo que es imposible de hacer en una compresión por row, lo que incrementa aun más el nivel de compresión.

Un gran ratio de compresión me permite tener más información en el cache de datos, incrementar fuertemente los aciertos del buffer y evitar el acceso a I/O, que es la operación más costosa en una base de datos.
En las pruebas hechas por los laboratorios de Microsoft sobre datos reales y haciendo la comparativa con SQL Server 2008 R2, en algunos casos se obtuvo un incremento de hasta 60 veces la performance de una consulta. Lo cual resulta un número bastante impresionante.

¿Como se usa un índice por columna?
Si bien todavía la documentación oficial en SQL Server 2011 no está disponible porque el producto no fue liberado, si podemos ver la sintaxis si entramos a la web del sitio.
Para crear un índice por columna simplemente deberemos anteponer la palabra clave COLUMNSTORE.
Ejemplo:

 
CREATE COLUMNSTORE INDEX NuevoIndice ON Personas
(
FechaDeVenta,
FechaDeEntrega,
Producto,
Precio,
Cantidad
)
 

¿Siempre va a convenir entonces usar este tipo de índices?
La respuesta es un rotundo no. Los índices por columna es un índice más que incrementa notablemente la performance en bases de datos muy grandes y en determinado tipo de consultas. Pero son índices pensados para escenarios de datawharehousing, especialmente para consultas del tipo star join. No en todos los casos es mas óptimo este tipo de índice ni tampoco están pensados para las típicas bases de datos transaccionales OLTP. Para una query normal, sigue siendo mas útil usar los índices b-tree clásicos. El motor de SQL Server en función de sus estadísticas, sabrá elegir cuando es más conveniente usar un índice por columna o un índice común.
Por otra parte, este tipo de índices en SQL Server tienen por el momento varias restricciones. No todos los tipos de datos son soportados y más importante aún, no se pueden hacer operaciones de INSERT, UPDATE, DELETE o MERGE sobre tablas con este tipo de índices. La manera de llenar una tabla entonces es deshabilitar el índice temporalmente, llenar la tabla y volver a habilitar el índice. Otra opción es crear una vista indexada con columnstore index sobre la tabla y dejar a esta tabla sin este tipo de índice.
Por ultimo, otro dato a tener en cuenta, que la reconstrucción de un column index lleva entre 2 y 3 veces mas tiempo, que un índice b-tree clásico.

Conclusión:
Lamentablemente la primera CTP de SQL Server 2011 que lanzó Microsoft todavía no incluye esta feature, por lo tanto, no la podemos probar y verificar si el aumento de su rendimiento es tan significativo como ellos dicen. Sin embargo, el índice por columna es una característica muy distintiva y que hasta el momento, ni Oracle ni DB2 pudieron incorporar nativamente en su producto relacional.
Seguramente con el correr de los tiempos y a medida que tengamos mas información, van a aparecer en blogs y en artículos, distintas comparaciones y escenarios en donde conviene utilizar índices por columnas o el clásico índice por filas.

Links interesantes:
ColumnStores vs. RowStores: How Different Are They Really?
Columnstore Indexes for Fast Data Warehouse Query Processing in SQL Server 11.0

1 comentario »

  1. Excellent information and facts could be identified on this net website.

    Comentario por nqrkyxpzvh@hotmail.co.uk — febrero 3, 2014 @ 5:45 pm


RSS feed for comments on this post. TrackBack URI

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Crea un blog o un sitio web gratuitos con WordPress.com.

A %d blogueros les gusta esto: