2011-03-31 16 views
6

Tengo una tabla con una columna de Identidad Id.Obtener el valor máximo para la columna de identidad sin una exploración de tabla

cuando ejecuto:

select max(Id) from Table 

SQL Server hace un recorrido de tabla y el agregado corriente.

Mi pregunta es, ¿por qué no puede simplemente buscar el último valor asignado a Id? Es un identity, por lo que la información debe ser rastreado, ¿verdad?

¿Puedo consultarlo de forma manual?

+2

¿Es el 'Id' también el índice agrupado? –

+0

@Joe no, no es – Blorgbeard

Respuesta

16

Puede usar IDENT_CURRENT para buscar el último valor de identidad que se va a insertar, p. Ej.

IDENT_CURRENT('MyTable') 

Sin embargo, tenga cuidado al usar esta función. Una transacción fallida aún puede incrementar este valor y, como dice Quassnoi, esta fila podría haberse eliminado.

Es probable que realice una exploración de tabla porque no puede garantizar que el último valor de identidad sea el valor MAX. Por ejemplo, la identidad puede no ser un simple entero creciente. Podría usar un número decreciente como su identidad.

5

¿Qué sucede si ha eliminado el registro más reciente?

El valor de IDENTITY ya no correspondería a los datos reales.

Si desea que las búsquedas rápidas para MAX(id), se debe crear un índice en el mismo (o probablemente declarará una PRIMARY KEY)

+0

Buen punto (aunque no elimino registros en esta tabla) – Blorgbeard

+3

@Blorgbeard: seguro, creo que es 'SQL Server' que no. – Quassnoi

+0

Sí, entiendo eso. Hay muchas buenas razones en este hilo para que olvide todo el asunto y me quede con Max (Id) :) – Blorgbeard

0

es el ID de la clave principal o indexados? Parece que debería hacer una búsqueda en esos casos.

+0

No, no hay ningún índice y no es el PK – Blorgbeard

+1

@Blorgbeard Dado que IDENT_CURRENT() puede no reflejar los datos en su tabla, no se puede usar para MAX() y no tiene índices, por lo que termina con una exploración de tabla . –

1

Estoy bastante seguro de que podría configurar un índice en ese campo en orden descendente y lo usaría para encontrar la clave más grande. Debería ser rápido.

+0

Funcionaría, pero no tengo permiso para agregar un índice a este DB solo para este – Blorgbeard

3

¿La tabla está agrupada en esa columna? Se puede utilizar Top 1:

SELECT TOP 1 [ID]  
FROM [Table] 
order by ID desc 
+0

No está agrupado en Id. Intenté esto, pero hace una exploración/clasificación que es más lenta que Max (ID). – Blorgbeard

1

Usted puede ejecutar esta instrucción siguiente y retire el último UNION ALL. Ejecute esta declaración para obtener los valores de Identidad actuales.

SELECT 
    ' SELECT '+char(39)+[name]+char(39)+' AS table_name, IDENT_CURRENT('+char(39)+[name]+char(39)+') AS currvalue UNION ALL' 
    AS currentIdentity 
FROM sys.all_objects WHERE type = 'U' 
Cuestiones relacionadas