2009-08-19 25 views
24

Así, recientemente, un DBA está tratando de decirnos que no podemos usar la sintaxis deSQL Server SELECT INTO y bloqueo con tablas temporales

SELECT X, Y, Z 
INTO #MyTable 
FROM YourTable 

Para crear tablas temporales en nuestro medio ambiente, debido a que la sintaxis provoca un bloqueo en TempDB durante la ejecución del procedimiento almacenado. Ahora, he encontrado una serie de cosas que detallan cómo funcionan las tablas temporales, el alcance de la ejecución, la limpieza y similares. Pero por mi vida, no veo nada sobre el bloqueo debido a su uso.

Estamos tratando de encontrar pruebas de que no deberíamos tener que pasar y hacer CREATE TABLE #MyTable ... para todas nuestras tablas temporales, pero ninguna de las partes podemos encontrar pruebas. Estoy buscando alguna información que la gente tenga.

Información adicional

Actualmente trabajando con SQL Server 2005, y que pronto será Server 2008 (ediciones Enterprise) SQL

+0

¿Por qué no lo pruebas? – automatic

+0

Hemos estado, y no veo ningún bloqueo ..... Estamos tratando de encontrar alguna forma de prueba, o mejor aún documentación –

Respuesta

34

Este consejo ha estado flotando alrededor for a long time:

Los cuellos de botella en SQL Server 6.5

Mucha gente utiliza un SELECT ... INTO consulta para crear una tabla temporal, algo así:

SELECT * EN #temptable DE SourceTable

Si bien esto w orks, crea bloqueos contra la base de datos tempdb para el duración de la instrucción SELECT ( bastante tiempo si se pesca de arrastre a través de una gran cantidad de datos en la tabla de origen , y aún más tiempo si el SELECT ... INTO está en el inicio de una transacción explícita de mayor duración) Mientras que el bloqueo está en su lugar, ningún otro usuario puede crear tablas temporales. La ubicación real del cuello de botella es un bloqueo en las tablas del sistema tempdb. En posteriores versiones de SQL Server, el modelo de bloqueo ha cambiado y el problema es evitarse.

Afortunadamente, solo fue un problema para SQL 6.5. Fue arreglado en 7.0 y más tarde.

+3

+1 Creo que los consejos del dba caen bajo la categoría de mitología –

+0

+1 para obtener el enlace a una solución estelar - DONDE 1 = 0 – SqlRyan

+0

¿Puede actualizar su respuesta con la nueva funcionalidad de SQL a medida que su respuesta aparece primero en Búsqueda de Google y debe ser válida para la última versión. TIA :) –

0

yo diría que la falta de la prueba de bloqueo significa que no hay bloqueo, que es su prueba. ¿Por qué el método en el que se crea la tabla temporal (CREAR o SELECCIONAR ... EN) marca la diferencia al bloquear TempDB?

+0

Ese es nuestro pensamiento y argumento también ... pero son insistiendo en que usar SELECT INTO causa bloqueo durante la duración del procedimiento almacenado. –

+0

Me pregunto por qué la tabla de temperatura que se está bloqueando es una preocupación también. Si fuera una tabla temporal global, esa es una historia diferente. –

+0

@rexem: El DBA del OP no dice que la tabla temporal esté bloqueada, sino que TempDB, la ubicación de todas las tablas temporales y el almacenamiento de otras temperaturas está bloqueado. No tengo idea de si el DBA es correcto o no, de la gente más sabia. –

0

Bueno, si eso fuera cierto, entonces mssql tendría problemas, ya que cualquier consulta de gran tamaño puede hacer uso de tempdb para mantener una copia de las filas. Esto a menudo se puede ver en los planes de consulta como un spool de tabla o puede ser utilizado por el operador HASH JOIN si se queda sin memoria para sus depósitos.

Usted puede mirar en el uso de las variables de tabla, que Mssql tratará de almacenar en la memoria y pasar a tempdb si crecen a grandes.

DECLARE @foo TABLE (x int, y int, z int) 
INSERT INTO @foo(x, y, z) SELECT x, y, z FROM YourTable 

Por supuesto, debe evaluar si primero se requiere la tabla temporal y la copia. Aunque si la consulta es lo suficientemente compleja como para usar una tabla temporal es mucho más legible, también podría ser lo suficientemente compleja como para que una tabla temporal valga la pena.

16

Esto probablemente flotará durante mucho tiempo, alimentando los bolsillos de varios "consultores". Como todos los mitos, tiene un núcleo de verdad y una gran cantidad de BS.

La verdad: SQL 2000 y las versiones anteriores tenían problemas de contención conocidos en torno a la asignación de extensiones en tempdb. De hecho, la afirmación era cierta en todas las bases de datos, pero más visible en tempdb debido a un uso intensivo de tempdb. Está documentado en KB328551:

Cuando la base de datos tempdb es muy utilizado , SQL Server puede experimentar contención cuando se trata de asignar páginas.

Desde la salida de la tabla de sistema sysprocesses , la waitresource pueden mostrar hasta como "2: 1: 1" (PFS página) o "2: 1: 3" (SGAM página). Dependiendo del grado de contención , esto también puede llevar a SQL Servidor que no responde por cortos períodos.

Estas operaciones utilizan fuertemente tempdb:
Creación y eliminación repetidas de tablas temporales (locales o globales).
Variables de tabla que usan tempdb para el almacenamiento propósitos.
Mesas de trabajo asociadas con CURSORES.
Tablas de trabajo asociadas con una cláusula ORDER BY.
Tablas de trabajo asociadas con una cláusula GROUP BY.
Archivos de trabajo asociados con HASH PLANS.

El uso intensivo y significativo de estas actividades puede conducir a la contención problemas.

Una traza se añadió bandera -T1118 en SQL Server 2000 SP3 que obligaba SQL para utilizar un algoritmo de round-robin para páginas mixtas asignaciones. Este nuevo algoritmo, cuando se correlaciona con la práctica de implementar tempdb encima de un conjunto de archivos de igual tamaño, uno para cada CPU, aliviaría la disputa. El indicador de seguimiento aún está presente en SQL 2005/2008, aunque es mucho menos probable que sea necesario.

Todo lo demás acerca de este mito es más o menos BS.

  • ¿utiliza #temp tables cause blocking? No. En el peor de los casos, aumenta la contención bajo la carga en SQL 2000 y versiones anteriores, pero eso está muy lejos de decir que bloquea cualquier cosa. Tendría que medir primero y ver que este es el caso, y si es así implementar las medidas correctivas (asignar un archivo tempdb por CPU, hacerlos de igual tamaño, activar -T1118) ..
  • Selecciona ... en #temp bloquear algo durante la selección? Realmente no.
  • Selecciona ... en el bloque #temp algo durante la duración del procedimiento almacenado que contiene la selección? Diablos no Solo leí esa afirmación y estallé en carcajadas.

Para obtener más detalles, hay este artículo: Misconceptions around TF1118.

+0

¡Gracias por esta información! –

+1

si [seleccione ... en #temp] está en transacción, antes de que la transacción se comprometa, [select * from sysobjects] se bloqueará en cualquier otra sesión. –

0

SELECT INTO #temp_table tiene un bloqueo shema en tempdb durante el tiempo de la declaración porque parte del trabajo que está logrando es crear la tabla. Esto es fundamentalmente diferente que crear primero la tabla usando CREATE TABLE #.... y luego ejecutar un conjunto basado en INSERT. SELECT INTO tiene ventajas sobre INSERT, en particular, la operación se registra mínimamente si el modelo de recuperación de la base de datos es simple o acumulada de registro.

10

¿Por qué no hacer lo siguiente?

SELECT X, Y, Z 
INTO #MyTable 
FROM YourTable 
WHERE 1 = 2 

La declaración correría al instante - crear su tabla temporal y evitar cualquier bloqueo posible. Posteriormente, se podría insertar en ella como de costumbre:

INSERT #MyTable 
SELECT X, Y, Z 
FROM YourTable 
+1

+1 para hacks que explotan las lagunas en el sistema. – jp2code

1

Usted puede conseguir el bloqueo si crea #temp mesas dentro de una transacción. Si bien esto generalmente no se recomienda, he visto esto mucho.

Sin embargo, el bloqueo que esto causa está en algunas tablas del sistema en tempdb que no afectan a otras conexiones desde la creación de tablas temporales (excepto tal vez para las versiones SQL anteriores a 2000?). Significa que ejecutar sp_spacesused en tempdb se bloqueará a menos que establezca el nivel de aislamiento de transacción para que no se lea. También las propiedades de visualización en tempdb de SSMS fallarán y el tiempo de espera sin duda se debe a que está utilizando el nivel de aislamiento de transacción comprometido de lectura.

Cuestiones relacionadas