GuilleSQL :: Microsoft SQL Server, SSIS, y más !!

SELECT INTO vs INSERT INTO: Conclusiones y Recomendaciones

Volver a: [SELECT INTO, INSERT INTO y el LOG de SQL Server: alternativas para cargar tablas en un Data Warehouse]


Este último capítulo incluye un resumen con las conclusiones obtenidas a lo largo de todo el artículo, principalmente un conjunto de recomendaciones cara al diseño y desarrollo de procesos de carga con SELECT INTO e INSERT INTO en SQL Server, que nos pueda servir como recordatorio general de buenas prácticas: la importancia del Modo de Recuperación (Recovery), el correcto dimensionamiento de ficheros, utilización de TEMPDB como área temporal para operaciones SELECT INTO, dimensionamiento de la memoria RAM de SQL Server, indexación, particionamiento de SQL Server, etc.

Ya sólo queda finalizar con un pequeño resumen de recomendaciones, finalizando así con el presente artículo. Vamos a ello...

El Modo de Recuperación (Recovery) de nuestra base de datos, puede convertirse en nuestro gran aliado si realizamos Operaciones de Registro Mínimo. De hecho, incluso si no relizamos Operaciones de Registro Mínimo, un Modo de Recuperación Simple evitará la necesidad de realizar Copias de Seguridad de Log (Backup Log), con el consiguiente ahorro en operaciones de acceso a disco (además, nos permitirá poder tener ficheros de Log más pequeños y minimizar las operaciones de crecimiento del Log). Claro está que el Modo de Recuperación Simple es menos seguro, pues no permite recuperar hasta un momento dado (RESTORE STOPAT), y además, no dispondremos de Backups de Log que pueden resultarnos de mucha ayuda (ej: en Modo de Recuperación Completo, si perdemos un Backup Full, podemos recuperar el Backup Full anterior, y aplicar todos los Backups de Log hasta el momento del tiempo que deseemos, por ejemplo, un momento posterior al Backup Full perdido: tolerancia a fallo de backups ;-).

Si la base de datos destino utiliza el Modo de Recuperación Completo (recovery FULL), resulta de gran interés poder apoyarse en TEMPDB (por ejemplo, utilizando tablas temporales) o en alguna otra base de datos adicional que utilice el Modo de Recuperación SIMPLE, para poder minimizar la escrituras en el LOG de SQL Server, y así, mejorar sensiblemente el rendimiento de nuestros procesos de carga.

Recordar, que TEMPDB se crea cada vez que se inicia la instancia de SQL Server, en consecuencia, es importante establecer un tamaño por defecto de TEMPDB correctamente dimensionado, y ser conscientes que ante un reinicio de la instancia (ej: un balanceo del Grupo de Recursos del Cluster utilizado para SQL Server, en caso de tratarse una instalación de SQL Server en Cluster), perderemos el contenido de TEMPDB (el concepto de persistencia en TEMPDB es bastante relativo, jeje ;-).

Para el desarrollo de Cargas Incrementales (típico ejemplo de Data Warehouse), en muchas ocasiones interesa crear una primera tabla temporal con todas la filas (es decir, una carga completa) mediante una sentencia SELECT INTO sobre una base de datos en Modo de Recuperación Simple. Seguidamente, realizaremos una operación INSERT INTO sobre la tabla definitiva, en esta ocasión sólo con las filas estrictamente necesarias (Carga Incremental). Debe recordarse, que muchas veces al trabajar con Tablas Versionadas o Tablas SCD Tipo 2, resulta especialmente dificil poder determinar directamente las filas incrementas que deseamos cargar (es decir, resulta especialmente dificil evitar el primer SELECT INTO que antes comentamos), existiendo casos en que se realizan modificaciones con efecto retroactivo en los datos origen, se realizan modificaciones manuales en los datos origen, etc. Un ejemplo típico es la creación de una nueva versión sobre una tabla SCD de Tipo 2. Si tenemos una Póliza con una única versión, con Fecha Desde a 01/01/2008 y Fecha Hasta a 31/12/9999, y se crea una nueva versión con Fecha Desde 01/01/2009 y Fecha Hasta 31/12/2009, también se modificará la versión original (en particular el campo Fecha Hasta, cerrándolo a 31/12/2008). Si esta nueva versión se crea en Febrero de 2009 (es decir, es un cambio con efecto retroactivo), podría ser que en alguna carga anterior alguna fila de otra tabla estuviese relacionada con versión original, cuando después de la creación de la nuevo versión, debería relacionarse con la nueva versión (típico problema de la utilización de Claves Subrogadas). Este tipo de problemáticas, y otras más, suelen solucionarse de una forma más clara y sencilla realizando una carga en dos fases (SELECT INTO e INSERT INTO), aunque no quita que sea posible realizarlo en una única fase (eso sí, recordar que el código hay que mantenerlo, y que la rotación del personal invita a generar código de fácil mantenimiento).

Del mismo modo, también quiero comentar que en algunos procesos de carga críticos, se realiza una Carga Incremental mediante SELECT INTO, creando una tabla con el conjunto de filas incremental que posteriormente será agregado a la tabla destino (la cual se trata de una Tabla Particionada, utilizando ALTER TABLE SWITCH para cargar una partición vacía). Aquí se aprovecha el Particionamiento de SQL Server, para evitar tener que realizar el INSERT INTO sobre la tabla destino, con el objetivo de mejorar el rendimiento. Claro está, que no siempre resulta posible o intersante esta opción. Por ejemplo, si estamos cargando un fichero de Log (ej: el Log del ISA Server, un Application Log de Windows, etc.), podemos permitirnos el hecho cargar un mes completo como una partición, pero en otros casos (ej: pagos de primas en una empresa de seguros) puede que no podamos debido a que puedan insertarnos filas con efecto retroactivo (es decir, tendíamos que realizar modificaciones sobre múltiples particiones que ya estaban cargadas previamente, complicándose dicho proceso de carga).

Otro detalle a tener en cuenta, es que en la realización de Cargas Totales con operaciones INSERT INTO (y también con BCP y BULK INSERT), suele ser interesante eliminar los índices antes de realizar la carga, realizar la carga, y volver a crear los índices. Claro está, que en el caso de Cargas Incrementales, la eliminación y creación de índices suele aportar más inconvenientes que ventajas (es decir, que suele resultar mucho más costosa).

Resulta de gran importancia tener correctamente dimensionados nuestros ficheros de base de datos, tanto dimensionar los ficheros de datos, como dimensionar los ficheros de LOG. Con esto, no sólo me refiero al tamaño asignado a dichos ficheros. Es tan importante asignar un tamaño suficiente a los ficheros de datos y log, como configurar apropiadamente las opciones de crecimiento de los ficheros, pues estas últimas tienen un impacto directo en la generación de actividad de entrada salida extraordinaria.

Por supuesto, un buen dimensionamiento de la Memoria RAM de SQL Server será de gran ayuda. Recordemos, que SQL Server por defecto intentará consumir toda la memoria RAM que le sea necesario sin hacer incurrir en paginación al Sistema Operativo. En consecuencia, cuanta mayor memoria disponga nuestra Instancia de SQL Server, mayor será la cantidad de páginas de datos que se podrán mantener en memoria, y en consecuencia se podrá minimizar la necesidad de acceder a disco para la lectura de dichas páginas (el acceso a disco es quizás el principal cuello de botella para cualquier motor de base de datos).

Volver a: [SELECT INTO, INSERT INTO y el LOG de SQL Server: alternativas para cargar tablas en un Data Warehouse]




Miembros de
Miembros de GITCA (Global IT Community Association)

Menu de Usuario
  Iniciar Sesión
  Registrarse
  Restablecer Contraseña
  Ventajas de Registrarse

Acerca de
  Contigo desde Oct 2007
  771 usuarios registrados
  86146 pageloads/mes
  Ranking Alexa 498160

Social Networks
Sigue a Portal GuilleSQL en Linkedin !!
Sigue a Portal GuilleSQL en Twitter !!



Archivo

Abril de 2018 (3)
Marzo de 2018 (2)
Febrero de 2018 (7)
Enero de 2018 (1)
Diciembre de 2017 (15)
Noviembre de 2017 (7)
Junio de 2017 (3)
Mayo de 2017 (1)
Marzo de 2017 (3)
Enero de 2017 (4)
Junio de 2016 (1)
Mayo de 2016 (2)
Abril de 2016 (2)
Septiembre de 2015 (2)
Agosto de 2015 (2)
Junio de 2015 (10)
Mayo de 2015 (4)
Abril de 2015 (8)
Marzo de 2015 (11)
Octubre de 2014 (3)
Septiembre de 2014 (7)
Agosto de 2014 (5)
Julio de 2014 (2)
Mayo de 2014 (4)
Abril de 2014 (4)
Marzo de 2014 (4)
Febrero de 2014 (1)
Enero de 2014 (5)
Diciembre de 2013 (8)
Noviembre de 2013 (2)
Octubre de 2013 (7)
Septiembre de 2013 (6)
Agosto de 2013 (1)
Julio de 2013 (6)
Junio de 2013 (11)
Mayo de 2013 (7)
Abril de 2013 (6)
Febrero de 2013 (5)
Enero de 2013 (7)
Diciembre de 2012 (12)
Noviembre de 2012 (13)
Octubre de 2012 (5)
Septiembre de 2012 (3)
Agosto de 2012 (6)
Julio de 2012 (4)
Junio de 2012 (1)
Mayo de 2012 (2)
Abril de 2012 (7)
Marzo de 2012 (16)
Febrero de 2012 (9)
Enero de 2012 (5)
Diciembre de 2011 (10)
Noviembre de 2011 (10)
Octubre de 2011 (4)
Septiembre de 2011 (5)
Agosto de 2011 (2)
Julio de 2011 (2)
Junio de 2011 (4)
Mayo de 2011 (2)
Abril de 2011 (6)
Marzo de 2011 (4)
Febrero de 2011 (10)
Enero de 2011 (5)
Diciembre de 2010 (6)
Noviembre de 2010 (4)
Octubre de 2010 (8)
Septiembre de 2010 (4)
Agosto de 2010 (1)
Julio de 2010 (3)
Mayo de 2010 (5)
Abril de 2010 (6)
Marzo de 2010 (8)
Febrero de 2010 (3)
Enero de 2010 (1)
Diciembre de 2009 (9)
Noviembre de 2009 (14)
Octubre de 2009 (2)
Septiembre de 2009 (8)
Agosto de 2009 (2)
Julio de 2009 (10)
Junio de 2009 (9)
Mayo de 2009 (10)
Abril de 2009 (9)
Marzo de 2009 (3)
Febrero de 2009 (2)
Enero de 2009 (3)
Noviembre de 2008 (2)
Octubre de 2008 (2)
Septiembre de 2008 (2)
Agosto de 2008 (5)
Julio de 2008 (5)
Junio de 2008 (1)
Mayo de 2008 (3)
Abril de 2008 (2)
Marzo de 2008 (2)
Febrero de 2008 (2)
Enero de 2008 (5)
Noviembre de 2007 (2)
Octubre de 2007 (2)






Copyright © 2007 GuilleSQL, todos los derechos reservados.