2011-04-07 15 views
6

Estoy tratando de unir dos tablas relativamente simples, pero mi consulta está experimentando serias interrupciones. No estoy seguro de por qué, pero creo que podría tener algo que ver con la función 'entre'. Mi primera tabla es como la siguiente (con una gran cantidad de otras columnas, pero esto sería la única columna que estoy tirando):¿La función 'BETWEEN' es muy costosa en SQL Server?


RowNumber 
1 
2 
3 
4 
5 
6 
7 
8 

mi segunda tabla "Grupos" mis filas en "bloques", y tiene el siguiente esquema:


BlockID  RowNumberStart  RowNumberStop 
1   1     3 
2   4     7 
3   8     8 

el resultado deseado estoy mirando para conseguir es vincular RowNumber con el BlockID como a continuación, con el mismo número de filas de la primera tabla. Así, el resultado sería el siguiente:


RowNumber BlockID   
1   1 
2   1 
3   1 
4   2 
5   2 
6   2 
7   2 
8   3 

Con el fin de conseguir eso, he utilizado la siguiente consulta, escribiendo los resultados en una tabla temporal:


select A.RowNumber, B.BlockID 
into TEMP_TABLE 
from TABLE_1 A left join TABLE_2 B 
on  A.RowNumber between B.RowNumberStart and B.RowNumberStop 

table_1 y table_2 son en realidad tablas muy grandes . La Tabla 1 es de aproximadamente 122M Filas, y la TABLA_2 tiene alrededor de 65M filas. En la TABLA_1, RowNumber se define como 'bigint', y en TABLE_2, BlockID, RowNumberStart y RowNumberStop se definen como 'int'. No estoy seguro de que eso marque la diferencia, pero solo quería incluir esa información también.

La consulta se colgó durante ocho horas. Consultas similares sobre este tipo y volumen de datos no se acercan tanto a este tiempo. Así que me pregunto si podría ser la declaración 'entre' que cuelga esta consulta.

Definitivamente agradeceríamos cualquier sugerencia sobre cómo hacer esto más eficiente.

+0

¿Has mirado el plan de ejecución? – HLGEM

+0

nunca visto entre usado en una unión antes de – DForck42

Respuesta

5

ENTRE es simplemente la abreviatura de:

select A.RowNumber, B.BlockID 
into TEMP_TABLE 
from TABLE_1 A left join TABLE_2 B 
on  A.RowNumber >= B.RowNumberStart AND A.RowNumber <= B.RowNumberStop 

Si el plan de ejecución pasa de B a A (pero dejó unirse indicaría que tiene que ir de A a B, en realidad), entonces yo estoy asumiendo es table_1 indexado en RowNumber (y eso debería estar cubriendo en esta consulta). Si solo tiene un índice agrupado en RowNumber y la tabla es muy amplia, recomiendo un índice no agrupado solo en RowNumber, ya que de esa manera cabrá muchas más filas por página.

De lo contrario, quiere indexar en la TABLA_2 en RowNumberStart DESC o RowNumberStop ASC, porque para una A necesitaría un DESC en RowNumberStart para que coincida.

Creo que es posible que desee cambiar su unión a INNER JOIN, la forma en que se configuran sus criterios de unión. (¿Alguna vez va a obtener la TABLA_1 en ningún bloque?)

Si mira su plan de ejecución, debe obtener más pistas sobre por qué el rendimiento puede ser malo, pero el criterio de Detención probablemente no se use en la búsqueda en la TABLA_1.

Lamentablemente, se ha eliminado la respuesta de SQLMenace sobre SELECT INTO.Mi comentario con respecto a eso estaba destinado a ser: @Martin SELECT INTO el rendimiento no es tan malo como lo era antes, pero aún así recomiendo CREATE TABLE para producción más porque SELECT INTO deducirá tipos y NULLability. Esto está bien si verifica que está haciendo lo que cree que está haciendo, pero crear una columna varchar o decimal muy larga con una precisión muy extraña puede dar como resultado no solo tablas impares, sino problemas de rendimiento (especialmente con algunos de los grandes varchards cuando Olvidas una IZQUIERDA o lo que sea). Creo que solo ayuda dejar en claro lo que esperas que sea la mesa. A menudo seleccionaré INTO usando WHERE 0 = 1 y verificará el esquema y luego lo guionará con mis ajustes (como agregar una IDENTIDAD o agregar una columna con una marca de tiempo predeterminada).

+0

La unión interna tiene sentido, así que cambié la consulta para ser una unión interna. Además, utilicé índices como sugirió, y la consulta se ejecutó en aproximadamente 20 minutos más o menos. ¡Muchas gracias por la ayuda! – Bobb

1

Tiene un problema principal: desea mostrar demasiado volumen de datos a la vez. Ar realmente está seguro de que desea manejar el resultado de TODOS 122M filas de la tabla 1 a la vez? ¿En serio necesitas eso?

+4

él está insertando en una tabla que no selecciona de una tabla – SQLMenace

+1

Buen punto, extrañé que –

Cuestiones relacionadas