En SQL Server 2005, podemos crear tablas temporales de dos maneras:
declare @tmp table (Col1 int, Col2 int);
o
create table #tmp (Col1 int, Col2 int);
¿Cuáles son las diferencias entre estos dos? He leído opiniones contradictorias sobre si @tmp todavía usa tempdb o si todo sucede en la memoria.
¿En qué escenarios uno supera al otro?
sql-server
temp-tables
table-variable
Eric Z Beard
fuente
fuente
Respuestas:
Existen algunas diferencias entre las Tablas temporales (#tmp) y las Variables de tabla (@tmp), aunque usar tempdb no es una de ellas, como se detalla en el siguiente enlace de MSDN.
Como regla general, para volúmenes de datos pequeños a medianos y escenarios de uso simples, debe usar variables de tabla. (Esta es una directriz demasiado amplia con, por supuesto, muchas excepciones; consulte los artículos siguientes y siguientes).
Algunos puntos a considerar al elegir entre ellos:
Las tablas temporales son tablas reales, por lo que puede hacer cosas como CREAR ÍNDICES, etc. Si tiene grandes cantidades de datos para los cuales el acceso por índice será más rápido, las tablas temporales son una buena opción.
Las variables de tabla pueden tener índices utilizando PRIMARY KEY o restricciones ÚNICAS. (Si desea un índice no único, simplemente incluya la columna de clave principal como la última columna en la restricción única. Si no tiene una columna única, puede usar una columna de identidad). SQL 2014 también tiene índices no únicos .
Las variables de tabla no participan en las transacciones y
SELECT
s están implícitamente conNOLOCK
. El comportamiento de la transacción puede ser muy útil, por ejemplo, si desea ROLLBACK a mitad de camino a través de un procedimiento, las variables de la tabla pobladas durante esa transacción aún se completarán.Las tablas temporales pueden provocar que los procedimientos almacenados se vuelvan a compilar, quizás a menudo. Las variables de la tabla no lo harán.
Puede crear una tabla temporal usando SELECT INTO, que puede ser más rápido de escribir (bueno para consultas ad-hoc) y puede permitirle lidiar con los tipos de datos cambiantes con el tiempo, ya que no necesita definir la estructura de su tabla temporal por adelantado.
Puede pasar las variables de tabla de las funciones, lo que le permite encapsular y reutilizar la lógica mucho más fácilmente (por ejemplo, hacer que una función divida una cadena en una tabla de valores en algún delimitador arbitrario).
El uso de variables de tabla dentro de las funciones definidas por el usuario permite que esas funciones se usen más ampliamente (consulte la documentación de CREAR FUNCIÓN para obtener más detalles). Si está escribiendo una función, debe usar variables de tabla sobre tablas temporales a menos que exista una necesidad imperiosa de lo contrario.
Ambas variables de tabla y tablas temporales se almacenan en tempdb. Sin embargo, las variables de la tabla (desde 2005) utilizan de manera predeterminada la clasificación de la base de datos actual frente a las tablas temporales que toman la clasificación predeterminada de tempdb ( ref ). Esto significa que debe tener en cuenta los problemas de intercalación si usa tablas temporales y su intercalación db es diferente a la de tempdb, causando problemas si desea comparar los datos en la tabla temporal con los datos de su base de datos.
Las tablas temporales globales (## tmp) son otro tipo de tabla temporal disponible para todas las sesiones y usuarios.
Algunas lecturas adicionales:
La gran respuesta de Martin Smith en dba.stackexchange.com
Preguntas frecuentes de MSDN sobre la diferencia entre los dos: https://support.microsoft.com/en-gb/kb/305977
Artículo de blog de MDSN: https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/tempdb-table-variable-vs-local-temporary-table
Artículo: https://searchsqlserver.techtarget.com/tip/Temporary-tables-in-SQL-Server-vs-table-variables
Comportamientos inesperados e implicaciones de rendimiento de tablas temporales y variables temporales: Paul White en SQLblog.com
fuente
Simplemente mirando el reclamo en la respuesta aceptada de que las variables de la tabla no participan en el registro.
En general, parece falso que haya alguna diferencia en la cantidad de registros (al menos para
insert
/update
/delete
operaciones en la tabla en sí, aunque desde entonces he encontrado que hay una pequeña diferencia a este respecto para los objetos temporales en caché en los procedimientos almacenados debido a la tabla del sistema adicional actualizaciones).Observé el comportamiento de registro en contra de
@table_variable
una#temp
tabla para las siguientes operaciones.Los registros de transacciones fueron casi idénticos para todas las operaciones.
La versión de la variable de tabla en realidad tiene algunas entradas de registro adicionales porque obtiene una entrada agregada (y luego eliminada de) la
sys.syssingleobjrefs
tabla base, pero en general tenía unos pocos bytes menos registrados simplemente ya que el nombre interno para las variables de tabla consume 236 bytes menos que para las#temp
tablas (118 menosnvarchar
caracteres ).Script completo para reproducir (mejor ejecución en una instancia iniciada en modo de usuario único y usando el
sqlcmd
modo)Resultados
fuente
INSERT ... SELECT
no se registraron mínimamente y no se puede establecerSELECT INTO ...
una variable de tabla.Para tablas más pequeñas (menos de 1000 filas) use una variable temporal, de lo contrario use una tabla temporal.
fuente
@wcm: en realidad, para elegir la variable de tabla no es solo Ram: se puede almacenar parcialmente en el disco.
Una tabla temporal puede tener índices, mientras que una variable de tabla solo puede tener un índice primario. Si la velocidad es un problema, las variables de la tabla pueden ser más rápidas, pero obviamente si hay muchos registros o la necesidad de buscar en la tabla temporal de un índice agrupado, entonces una tabla temporal sería mejor.
Buen artículo de antecedentes
fuente
Tabla temporal: una tabla temporal es fácil de crear y hacer una copia de seguridad de los datos.
Variable de tabla: Pero la variable de tabla implica el esfuerzo cuando generalmente creamos las tablas normales.
Tabla temporal: el resultado de la tabla temporal puede ser utilizado por varios usuarios.
Variable de tabla: Pero la variable de tabla solo puede ser utilizada por el usuario actual.
Tabla temporal: la tabla temporal se almacenará en tempdb. Hará tráfico de red. Cuando tenemos datos grandes en la tabla temporal, tiene que funcionar en la base de datos. Existirá un problema de rendimiento.
Variable de tabla: Pero una variable de tabla se almacenará en la memoria física para algunos de los datos, luego, cuando el tamaño aumente, se moverá a tempdb.
Tabla temporal: la tabla temporal puede hacer todas las operaciones DDL. Permite crear los índices, soltar, alterar, etc.,
Variable de tabla: mientras que la variable de tabla no permitirá realizar las operaciones DDL. Pero la variable de tabla nos permite crear solo el índice agrupado.
Tabla temporal: la tabla temporal se puede usar para la sesión actual o global. Para que una sesión de múltiples usuarios pueda utilizar los resultados en la tabla.
Variable de tabla: pero la variable de tabla se puede utilizar hasta ese programa. (Procedimiento almacenado)
Tabla temporal: la variable temporal no puede usar las transacciones. Cuando hacemos las operaciones DML con la tabla temporal, entonces puede revertir o confirmar las transacciones.
Variable de tabla: pero no podemos hacerlo para la variable de tabla.
Tabla temporal: las funciones no pueden usar la variable temporal. Además, no podemos hacer la operación DML en las funciones.
Variable de tabla: Pero la función nos permite usar la variable de tabla. Pero usando la variable de tabla podemos hacer eso.
Tabla temporal: El procedimiento almacenado realizará la recompilación (no puede usar el mismo plan de ejecución) cuando usemos la variable temporal para cada llamada subsiguiente.
Variable de tabla: mientras que la variable de tabla no será así.
fuente
Para todos los que creen en el mito de que las variables temporales están solo en la memoria
Primero, la variable de tabla NO es necesariamente residente en memoria. Bajo presión de memoria, las páginas que pertenecen a una variable de tabla se pueden enviar a tempdb.
Lea el artículo aquí: TempDB :: Tabla variable vs tabla temporal local
fuente
La otra diferencia principal es que las variables de tabla no tienen estadísticas de columna, como lo hacen las tablas temporales. Esto significa que el optimizador de consultas no sabe cuántas filas hay en la variable de la tabla (adivina 1), lo que puede conducir a que se generen planes altamente no óptimos si la variable de la tabla realmente tiene un gran número de filas.
fuente
rows
columna ensys.partitions
se mantiene para las variables de la tabla, por lo que realmente sabe cuántas filas hay en la tabla. Esto se puede ver usandoOPTION (RECOMPILE)
. Pero la falta de estadísticas de columna significa que no puede estimar predicados de columna específicos.Cita tomada de; Solución de problemas interna y profesional de SQL Server 2012
LAS VARIABLES DE LA MESA NO SE CREAN EN LA MEMORIA
Existe una idea errónea común de que las variables de tabla son estructuras en memoria y, como tales, funcionarán más rápido que las tablas temporales . Gracias a un DMV llamado sys. dm _ db _ session _ space _ use, que muestra el uso de tempdb por sesión, puede probar que ese no es el caso . Después de reiniciar SQL Server para borrar el DMV, ejecute el siguiente script para confirmar que su sesión _ id devuelve 0 para el usuario _ objetos _ alloc _ page _ count:
Ahora puede verificar cuánto espacio utiliza una tabla temporal ejecutando el siguiente script para crear una tabla temporal con una columna y llenarla con una fila:
Los resultados en mi servidor indican que a la tabla se le asignó una página en tempdb. Ahora ejecute el mismo script pero use una variable de tabla esta vez:
¿Cuál usar?
fuente
Otra diferencia:
Solo se puede acceder a una tabla var desde las declaraciones dentro del procedimiento que la crea, no desde otros procedimientos llamados por ese procedimiento o SQL dinámico anidado (a través de exec o sp_executesql).
El alcance de una tabla temporal, por otro lado, incluye código en procedimientos llamados y SQL dinámico anidado.
Si la tabla creada por su procedimiento debe ser accesible desde otros procedimientos llamados o SQL dinámico, debe usar una tabla temporal. Esto puede ser muy útil en situaciones complejas.
fuente
Las diferencias entre
Temporary Tables (##temp/#temp)
yTable Variables (@table)
son como:Table variable (@table)
se crea en elmemory
. Mientras que aTemporary table (##temp/#temp)
se crea entempdb database
. Sin embargo, si hay una presión de memoria, las páginas que pertenecen a una variable de tabla pueden ser empujadas a tempdb.Table variables
No pueden participar entransactions, logging or locking
. Esto hace@table faster then #temp
. Entonces la variable de tabla es más rápida que la tabla temporal.Temporary table
permite modificaciones de esquema a diferenciaTable variables
.Temporary tables
son visibles en la rutina creada y también en las rutinas secundarias. Mientras que las variables de tabla solo son visibles en la rutina creada.Temporary tables
están permitidosCREATE INDEXes
, mientras queTable variables
no están permitidos,CREATE INDEX
sino que pueden tener índice mediante el usoPrimary Key or Unique Constraint
.fuente
Considere también que a menudo puede reemplazar ambas con tablas derivadas que también pueden ser más rápidas. Sin embargo, al igual que con todos los ajustes de rendimiento, solo las pruebas reales contra sus datos reales pueden indicarle el mejor enfoque para su consulta en particular.
fuente
Me sorprende que nadie mencione que la diferencia clave entre estos dos es que la tabla temporal admite la inserción paralela, mientras que la variable de la tabla no. Debería poder ver la diferencia con el plan de ejecución. Y aquí está el video de los Talleres SQL en el Canal 9 .
Esto también explica por qué debería usar una variable temporal para tablas más pequeñas, de lo contrario, use una tabla temporal, como SQLMenace respondió antes.
fuente