Está en la página 1de 15

Tablas temporales SQL

Tablas temporales vistas desde el SQL

Versin 1.0
ndice

NDICE............................................................................................................................................................2
INTRODUCCIN...........................................................................................................................................3
PROBLEMTICA DE LAS TABLAS TEMPORALES................................................................................4
POSIBLES SOLUCIONES.............................................................................................................................5
TIPOS DE TABLAS TEMPORALES............................................................................................................6
FUNCIONAMIENTO DE TABLAS TEMPORALES...................................................................................7
OPTIMIZAR EL USO DE TABLAS TEMPORALES...................................................................................8
VARIABLES DE TABLA................................................................................................................................9

METODOLOGA DE DOCUMENTACIN
PGINA 2 DE 15
Introduccin

En el mundo de las bases de datos, dentro de SQL, es muy comn el uso de tablas temporales.
A pesar de que todo el mundo sabe que este tipo de estructuras hacen mas lento el
funcionamiento de las consultas, los programadores no podemos evitar recurrir a ellas ya que en
muchas oportunidades facilitan la resolucin de problemas. Almacenar datos para usarlos
posteriormente, guardar resultados parciales, analizar grandes cantidades de filas
Hay muchos casos en los que podemos necesitar estas tablas temporales, Pero hay que
utilizarlas correctamente!

METODOLOGA DE DOCUMENTACIN
PGINA 3 DE 15
Problemtica de las tablas temporales

El consejo que tenemos que seguir a la hora de trabajar con tablas temporales es simple: no usarlas.

Y por qu no? Hay un montn de razones que iremos desarrollando a lo largo de este documento,
pero para empezar veamos en que se traduce el utilizar una tabla temporal en SQL Server:

Las tablas temporales se crean en la tempdb, y al crearlas se producen varios bloqueos


sobre esta base de datos como por ejemplo en las tablas sysobjects y sysindexes. Los
bloqueos sobre la tempdb afectan a todo el servidor.

Como con cualquier tabla:

o Al crearlas es necesario que se realicen accesos de escritura al disco ( no


siempre si las tablas son pequeas)

o Al introducir datos en las tablas temporales de nuevo se produce actividad en el


disco, y ya sabemos que el acceso a disco suele ser el cuello de botella de
nuestro sistema.

o Al leer datos de la tabla temporal hay que recurrir de nuevo al disco. Adems
estos datos ledos de la tabla suelen combinarse con otros
o Al borrar la tabla de nuevo hay que adquirir bloqueos sobre la base de datos
tempdb y realizar operaciones en disco.

Al usar tablas temporales dentro de un procedimiento almacenado perdemos la ventaja


de tener compilado el plan de ejecucin de dicho procedimiento almacenado y se
producirn recompilaciones ms a menudo. Lo mismo pasar cuando el SQL Server
intenta reutilizar el plan de ejecucin de una consulta parametrizada. Si en la consulta
tenemos una tabla temporal difcilmente se reutilizar dicho plan de ejecucin.

METODOLOGA DE DOCUMENTACIN
PGINA 4 DE 15
Sobre este ultimo punto, vamos a mostrar un simple ejemplo que nos va a ayudar a entender
mejor el tema, para eso vamos a utilizar el fantastico trace del SQL, que nos va a ayudar a
mostrar lo que estamos escribiendo.

Ejemplo 1:

Vamos a ver un ejemplo simple y alejado de la realidad pero que ilustre lo que queremos
explicar en este texto. Vamos a utilizar la base de datos Northwind.
En esta base de datos los pedidos se envan a travs de tres compaas de trasnportes:
Speedy Express(1), United Package(2) y Federal Shipping(3). La compaa Federal Shipping
nos oferta realizar todos los envos que hacemos a travs de United Package al precio fijo de
10$.

Decidimos que este ahorro merece la pena y vamos a cambiar en nuestra base de datos
todos los pedidos que tienen que ser enviados por United Package para que sean enviados a
travs de Federal Shipping.

Para hacer esta actualizacin de los datos tenemos varias opciones. Vamos a comparar tres
formas de hacerlo.

(Invertimos el ejemplo para el Metodo 2, as vamos a poder ejecutar la prueba seguida sin
modificar los datos)

Mtodo 1: Tablas temporales

DECLARE @st datetime

SET @st =getdate()

CREATE TABLE #Actualizar (OrderId int, ShipVia int, Freight money)

INSERT INTO #Actualizar

SELECT OrderID, ShipVia, Freight


FROM Orders
WHERE ShipVia=2

UPDATE Orders SET


ShipVia=3,
Freight=10
WHERE OrderID IN (SELECT OrderID FROM #Actualizar)

DROP TABLE #Actualizar

PRINT 'Operacion completada en: ' + RTRIM(cast(datediff(ms,@st,getdate()) as char(10))) + '


milisegundos'

Resultado:
(581 row(s) affected)
(581 row(s) affected)
Operacion completada en: 110 milisegundos

Trace:

Text Event Class Duration


METODOLOGA DE DOCUMENTACIN
PGINA 5 DE 15
SET @st =getdate() SQL:StmtCompleted 0
CREATE TABLE #Actualizar (OrderId int,
ShipVia int, Freight money) SQL:StmtCompleted 0
SELECT statman([ShipVia],
[OrderID],@PSTATMAN) FROM
(SELECT TOP 100 PERCENT [ShipVia],
[OrderID] FROM [dbo].[Orders]
WITH(READUNCOMMITTED,SAMPLE
1.000000e+002 PERCENT) ORDER BY
[ShipVia],[OrderID]) AS
_MS_UPDSTATS_TBL OPTION
(BYPASS OPTIMIZER_QUEUE, MAX SP:StmtCompleted 0
SELECT
statman([OrderID],@PSTATMAN)
FROM (SELECT TOP 100 PERCENT
[OrderID] FROM [dbo].[Orders]
WITH(READUNCOMMITTED,SAMPLE
1.000000e+002 PERCENT) ORDER BY
[OrderID]) AS _MS_UPDSTATS_TBL
OPTION (BYPASS OPTIMIZER_QUEUE,
MAXDOP 1) SP:StmtCompleted 0
INSERT INTO #Actualizar SELECT
OrderID, ShipVia, Freight FROM Orders
WHERE ShipVia=2 SQL:StmtCompleted 0
SELECT
statman([OrderId],@PSTATMAN)
FROM (SELECT TOP 100 PERCENT
[OrderId] FROM [dbo].
[#Actualizar________________________
_________________________________
_________________________________
_______________000000003728]
WITH(READUNCOMMITTED,SAMPLE
1.0000 SP:StmtCompleted 0
UPDATE Orders SET ShipVia=3,
Freight=10 WHERE OrderID IN
(SELECT OrderID FROM #Actualizar) SQL:StmtCompleted 32
DROP TABLE #Actualizar SQL:StmtCompleted 0
PRINT 'Operacion completada en: ' +
RTRIM(cast(datediff(ms,@st,getdate()) as
char(10))) + ' milisegundos' SQL:StmtCompleted 0

METODOLOGA DE DOCUMENTACIN
PGINA 6 DE 15
Mtodo 2: Variables tipo tabla

DECLARE @st datetime

SET @st =getdate()

DECLARE @Actualizar TABLE(OrderId int, ShipVia int, Freight money)

INSERT INTO @Actualizar


SELECT OrderID, ShipVia, Freight
FROM Orders
WHERE ShipVia=3

UPDATE Orders SET


ShipVia=2,
Freight=10
WHERE OrderID IN (SELECT OrderID FROM @Actualizar)

PRINT 'Operacion completada en: ' + rtrim(cast(datediff(ms,@st,getdate()) AS char(10))) + '


milisegundos'

Resultado:
(581 row(s) affected)
(581 row(s) affected)
Operacion completada en: 30 milisegundos

Trace:
Text Event Class Duration
SET @st =getdate() SQL:StmtCompleted 0
INSERT INTO @Actualizar SELECT
OrderID, ShipVia, Freight FROM Orders
WHERE ShipVia=3 SQL:StmtCompleted 0
UPDATE Orders SET ShipVia=2,
Freight=10 WHERE OrderID IN
(SELECT OrderID FROM @Actualizar) SQL:StmtCompleted 31
PRINT 'Operacion completada en: ' +
rtrim(cast(datediff(ms,@st,getdate()) AS
char(10))) + ' milisegundos' SQL:StmtCompleted 0

Mtodo 3: Sin tablas temporales

DECLARE @st datetime

SET @st =getdate()

UPDATE Orders SET


ShipVia=2,
Freight=10
WHERE OrderID IN (SELECT OrderID FROM Orders WHERE ShipVia=3 )

PRINT 'Operacion completada en: ' + rtrim(cast(datediff(ms,@st,getdate()) AS char(10))) + '


milisegundos'

METODOLOGA DE DOCUMENTACIN
PGINA 7 DE 15
Resultado:
(581 row(s) affected)
Operacion completada en: 30 milisegundos

Trace:

Text Event Class Duration


SET @st =getdate() SQL:StmtCompleted 0
UPDATE Orders SET ShipVia=2,
Freight=10 WHERE OrderID IN
(SELECT OrderID FROM Orders WHERE
ShipVia=3 ) SQL:StmtCompleted 31
PRINT 'Operacion completada en: ' +
rtrim(cast(datediff(ms,@st,getdate()) AS
char(10))) + ' milisegundos' SQL:StmtCompleted 0

Desde luego este ejemplo no es significativo, y en cada caso hay que estudiar la situacin y comparar
los resultados obtenidos en un entorno de trabajo para saber cual es la mejor opcin.

NOTA:
Sabemos que la mejor solucin para dicha consulta es la siguiente:

UPDATE Orders SET


ShipVia=3,
Freight=10
WHERE ShipVia=2

Lo que se intenta demostrar con estos ejemplos, son las diferencias de tiempos entre las distintas
soluciones mostradas.

Vistos estos problemas creo que no hace falta repetir nuestro consejo

METODOLOGA DE DOCUMENTACIN
PGINA 8 DE 15
Posibles soluciones

En lugar de tablas temporales podemos mejorar nuestro cdigo para que no sean necesarias,
podemos usar subconsultas (normalmente usar una subconsulta mejora drsticamente el rendimiento
respecto a usar tablas temporales), usar tablas permanentes, usar tablas derivadas ya que las mismas
se resuelven en memoria y reducen el uso del disco.

Hay que recordar siempre que cualquier alternativa es buena si evitamos usar tablas temporales
(cursores excluidos por supuesto!, ya lo veremos en otra oportunidad)

Vamos a mostrar un ejemplo de cmo remplazar una tabla temporal por una subconsulta. Para ello
vamos a utilizar tambin la base de datos de Northwind.

Ejemplo 2:

Mtodo 1: Tablas temporales

-- Crea la tabla temporal

CREATE TABLE #Temp_Ejemplo (


[CategoryID] INT NOT NULL,
[Category_Count] INT NOT NULL
)

-- Inserta valores dentro de la tabla temporal

INSERT INTO #Temp_Ejemplo (CategoryID, Category_Count)


SELECT C.CategoryID, COUNT(*) AS Category_Count
FROM Categories C
INNER JOIN Products P ON C.CategoryID = P.CategoryID
GROUP BY C.CategoryID, C.CATEGORYNAME

-- JOINEA la tabla temporal para obtener los valores

SELECT C.CategoryID, C.CategoryName, P.ProductName, P.UnitPrice,


#Temp_Ejemplo.Category_Count
FROM Categories C
INNER JOIN Products P ON C.CategoryID = P.CategoryID
INNER JOIN #Temp_Ejemplo ON C.CategoryID = #Temp_Ejemplo.CategoryID
ORDER BY C.CategoryName

-- borra la tabla temporal

DROP TABLE #Temp_Ejemplo

Mtodo 2: Sin tablas temporales con subconsulta

METODOLOGA DE DOCUMENTACIN
PGINA 9 DE 15
-- Reemplaza la tabla temporal con una subconsulta
SELECT C.CategoryID, C.CategoryName, P.ProductName, P.UnitPrice, CT.Category_Count
FROM Categories C
INNER JOIN Products P ON C.CategoryID = P.CategoryID
INNER JOIN (
SELECT C.CategoryID, COUNT(*) AS Category_Count
FROM Categories C
INNER JOIN Products P ON C.CategoryID = P.CategoryID
GROUP BY C.CategoryID, C.CategoryName
)CT ON C.CategoryID = CT.CategoryID
ORDER BY C.CategoryName

Las dos consultas, son iguales, devuelven el mismo valor,

De todos modos si alguna vez tenemos que usarlas es mejor conocerlas bien.
No se puede generalizar y decir que una consulta con tablas temporales ser peor que otra consulta
sin tablas temporales que extrae la misma informacin, lo ideal es siempre tener alternativas, revisar
su plan de ejecucin y sobre todo probar eso nos dar la experiencia necesaria para poder saber
cuando usar un tipo de sentencia.

METODOLOGA DE DOCUMENTACIN
PGINA 10 DE 15
Tipos de tablas temporales

Las tablas temporales son de dos tipos en cuanto al alcance la tabla. Tenemos tablas temporales
locales y tablas temporales globales.

#locales

Las tablas temporales locales tienen una # como primer carcter en su nombre y slo se pueden
utilizar en la conexin en la que el usuario las crea. Cuando la conexin termina la tabla temporal
desaparece. Por lo tanto se admiten tablas con el mismo nombre pero en distinta conexin aunque el
user sea el mismo. Sugerir la creacin y mostrar el nombre automtico que le asigna a la tabla.

##globales

Las tablas temporales globales comienzan con ## y son visibles por cualquier usuario conectado al
SQL Server. Y una cosa ms, estas tablas desaparecen cuando ningn usuario est haciendo
referencias a ellas, no cuando se desconecta el usuario que la creo.

Temp

Realmente hay un tipo ms de tablas temporales. Si creamos una tabla dentro de la base de datos
temp es una tabla real en cuanto a que podemos utilizarla como cualquier otra tabla en cualquier base
de datos, y es temporal en cuanto a que desaparece en cuanto apagamos el servidor.

METODOLOGA DE DOCUMENTACIN
PGINA 11 DE 15
Funcionamiento de tablas temporales

Crear una tabla temporal es igual que crear una tabla normal. Vemoslo con un ejemplo:

CREATE TABLE #TablaTemporal (Campo1 int, Campo2 varchar(50))

Y se usan de manera habitual.

INSERT INTO #TablaTemporal VALUES (1,Primer campo)

INSERT INTO #TablaTemporal VALUES (2,Segundo campo)

SELECT * FROM #TablaTemporal

Como vemos no hay prcticamente limitaciones a la hora de trabajar con tablas temporales (una
limitacin es que no pueden tener restricciones FOREING KEY)
NOTA: La deja crear pero con un warning

METODOLOGA DE DOCUMENTACIN
PGINA 12 DE 15
Optimizar el uso de tablas temporales

El uso que les podemos dar a este tipo de tablas es infinito, pero siempre teniendo en cuenta unas
cuantas directivas que debemos seguir para que ralenticen nuestro trabajo lo menos posible.

Por ejemplo no es mala costumbre crear las tablas temporales con comandos DDL como en el
ejemplo anterior (CREATE TABLE) y luego rellenarlas comandos INSERT o con INSERT INTO. Es
cierto que eso mismo lo podemos lograr en un nico paso con SELECT INTO, pero esta opcin es
peor porque los bloqueos que se adquieren sobre objetos del sistema duran ms tiempo.

Como siempre es mejor pedir los campos que queremos y no poner el tpico SELECT * FROM...

De la misma manera es muy recomendable cualificar los registros que queremos y no tener registros
que no vamos a utilizar en tablas temporales.

Otra buena costumbre es borrar nosotros nuestras tablas. S que es cierto que al terminar la conexin
las tablas temporales locales desaparecen, pero si tenemos un conjunto de sentencias largo y
creamos una tabla temporal al principio y no la vamos a utilizar en el resto del tiempo no tiene sentido
tener esa tabla ah ocupando espacio y memoria.

Si las tablas temporales son grandes una opcin para aumentar el rendimiento es crear un ndice que
nos ayude a recuperar los datos de esa tabla (para tablas pequeas es un gasto intil porque nunca
se usarn los ndices).

Colocar la base de datos tempdb en un disco dedicado solo para esta funcin aumentar el
rendimiento global del sistema si se hace un uso intensivo de tablas temporales.

Y por ltimo pero no menos importante, no crear tablas temporales dentro de transacciones ni dentro
de triggers la concurrencia de nuestra base de datos sufrir mucho si se utilizan.

METODOLOGA DE DOCUMENTACIN
PGINA 13 DE 15
Variables de tabla

Con SQL Server 2000 podemos declarar variables de tipo TABLE.


Este tipo de variables tienen una serie de ventajas sobre las tablas temporales por lo que siempre que
podamos escogeremos usar variables de tabla frente a tablas temporales.

Usar variables temporales es sencillo:

DECLARE @VariableTabla TABLE (Campo1 int, Campo2 char(50))

INSERT INTO @VariableTabla VALUES (1,'Primer campo')

INSERT INTO @VariableTabla VALUES (2,'Segundo campo')

SELECT * FROM @VariableTabla

Ventajas que encontraremos al usar variables de tipo tabla:

Tienen un mbito bien definido. El procedimiento almacenado, la funcin o el batch en el que


se declaran.

Las variables de tipo tabla producen menos recompilaciones de los procedimientos


almacenados en los que se encuentran que si utilizamos tablas temporales.

Las variables de tabla no necesitan de bloqueos ni de tantos recursos como las tablas
temporales.

Lo mas notorio es que las variables del tipo tabla apuntan a estructuras en memoria con lo
cual producen menos overhead que las tablas temporales

Las variables del tipo tabla al ser siempre locales al proceso que las creo no se pueden pasar
directamente como parmetros de un stored

Pero tambin tienen inconvenientes:

No podemos cambiar la definicin de la tabla una vez declarada

No podemos utilizar ndices que no sean agrupados

No se pueden utilizar en INSERT INTO ni en SELECT INTO

No podemos utilizar funciones en las restricciones

NOTA:

METODOLOGA DE DOCUMENTACIN
PGINA 14 DE 15
Si ponemos en una balanza las ventajas y los inconvenientes vemos que en general es mejor utilizar
las variables de tipo tabla que las tablas temporales. Solo en el caso de tener gran cantidad de datos
en una tabla temporal y si la vamos a usar varias veces es preferible la opcin de tablas temporales
porque en ellas podemos definir ndices.
Espero que esto nos sirva al menos para conocer un poco mejor a las tablas temporales.

NOTAS RELACIONADAS:
http://www.sql-server-performance.com/jg_derived_tables.asp

METODOLOGA DE DOCUMENTACIN
PGINA 15 DE 15

También podría gustarte