2011-07-27 19 views
8

Tenemos una base de datos SQL Server 2005 para la cual queremos mejorar el rendimiento de la eliminación masiva/insertar/seleccionar y noto que usa decimal(18,0) para sus claves principales. Entiendo que esto nos dará muchos más valores que bigint, pero esperábamos que sea una ganancia rápida y que nos dure muchos millones de años de crecimiento según mis cálculos.SQL Server BIGINT o DECIMAL (18,0) para la clave principal

veo en .NET docs decimales toman 16 bytes en lugar de los 8 requeridos por los largos, pero en SQL Server se ve como biginttake 8 bytes pero el decimal(18,0) lleva sólo 5 bytes - como también se observa por select DATALENGTH(max(id)) from table. ¿Es esto correcto?

¿Hay alguna otra razón por la cual bigint podría ser más lento o debería seguir con decimal(18,0)?

+4

en su caso decimal (18,0) toma 9 bytes, no 5 –

+0

La función DATALENGTH dice 5? –

Respuesta

8

DATALENGTH está lanzando a varchar antes de bytes de recuento. Entonces su valor máximo es < 100000.

Los 9 bytes se pueden probar con esto. sys.columns tiene una columna max_length (decimal es de longitud fija por lo que es siempre 9 bytes, antes de preguntar de otra manera)

CREATE TABLE dbo.foo (bar decimal(18,0)) 
GO 
SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('foo') 
GO 
DROP TABLE dbo.foo 
GO 

Por razones de legado, decimal(18, 0) se usó a menudo como sustituto de "número entero de 64 bits" antes de añadir bigint con SQL Server 2000.

decimal(18, 0) y bigint son aproximadamente el mismo en el rango de: decimal es de un byte más a las 9 bytes como por la documentación

Además de eso, entero normal será fraccionadamente (tal vez no medible) más rápido que el decimal. Diciendo eso, si se espera tener más de 4 mil millones de filas en el próximo año o 5, entonces el rendimiento debería ser importante. Si no es así, simplemente use int

+3

Un bigint cabe en un solo registro en una máquina de 64 bits, un decimal de 9 bytes no. Si hablamos de una clave principal que se usa en todas partes, esperaría que esto sea bastante costoso. –

20

Se obtiene este rango con bigint:

-2^63 to 2^63-1 

also known as roughly: 

-9.2 x 10^18 to 9.2 x 10^18 

Se obtiene este rango con decimal (18,0):

-10^18 to 10^18 

decimales: Almacenamiento Bytes por Precisión

Precision Storage Bytes 
1-9:   5 
10-19:  9 
20-28:  13 
29-38:  17 

tipos enteros y bytes de almacenamiento

integer type Storage Bytes 
bigint   8 
int    4 
smallint  2 
tinyint   1 

Pensamientos

Los dos ejemplos publicados en su pregunta en realidad producen prácticamente la misma cantidad de valores únicos.

Además, no verá un cambio de rendimiento significativo sin importar su elección, pero verá un cambio en la eficiencia para otros programadores en el equipo si comienza a usar decimales donde los programadores esperan un número entero. Este es un punto menor.

Para hacer frente a su problema específico, si desea una mayor gama, utiliza decimal (38,0). Esto le da:

-10^38 to 10^38 

Si usted está preocupado acerca de la velocidad, utilice la precisión mínima que va a durar toda la vida de su software.

Si no está midiendo el tiempo en nanosegundos, a continuación, elija la opción que se ajuste mejor a sus modos de pensar de los programadores y su deseo de tener una larga serie de números.

Referencias

Cuestiones relacionadas