SQL Server BIGINT или DECIMAL (18,0) для первичного ключа
у нас есть база данных SQL Server 2005, для которой мы хотим улучшить производительность массового удаления / вставки / выбора, и я замечаю, что она использует decimal(18,0)
для первичных ключей. Я понимаю, что это даст нам гораздо больше значений, чем bigint
но надеялся, что это может быть быстрая победа и должна длиться много миллионов лет роста по моим расчетам.
Я вижу в .net docs десятичные числа занимают 16 байт вместо 8, требуемых longs, но в SQL Server это выглядит так bigint
занимают 8 байт но decimal(18,0)
принимает только 5 байт - как Также видно select DATALENGTH(max(id)) from table
. Правильно ли это?
есть ли другая причина bigint
может быть медленнее, или я должен придерживаться decimal(18,0)
?
2 ответов
DATALENGTH бросает в varchar перед подсчетом байтов. Так что ваш Макс значение
9 байтов можно доказать с этим. sys.колонки имеет столбец max_length (decimal-фиксированная длина, поэтому всегда 9 байт, прежде чем вы спросите иначе)
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
по причинам наследия,decimal(18, 0)
часто использовался в качестве суррогата для "64-битного целого числа" до добавления bigint с SQL Server 2000.
decimal(18, 0)
и bigint
примерно одинаковые диапазон: decimal - это еще один байт при 9 байтах согласно документации
кроме того, простое целое число будет дробно (возможно, не измеримо) быстрее, чем десятичное. Говоря, что если в следующем году ожидается более 4 миллиардов строк или 5, то производительность должна иметь значение. Если это не так, то просто используйте int
вы получаете этот диапазон с bigint:
-2^63 to 2^63-1
also known as roughly:
-9.2 x 10^18 to 9.2 x 10^18
вы получаете этот диапазон с decimal (18,0):
-10^18 to 10^18
Decimal: байты хранения на точность
Precision Storage Bytes
1-9: 5
10-19: 9
20-28: 13
29-38: 17
целочисленные типы и байты хранения
integer type Storage Bytes
bigint 8
int 4
smallint 2
tinyint 1
мысли
два примера, опубликованные в вашем вопросе, фактически дают практически одинаковое количество уникальных значений.
кроме того, вы вы не увидите значительного изменения производительности независимо от вашего выбора, но вы увидите изменение эффективности для других программистов в команде, если вы начнете использовать десятичные дроби, где программисты ожидают целое число. Это незначительный момент.
чтобы решить вашу конкретную проблему, если вы хотите больший диапазон, используйте Decimal (38,0). Это дает вам:
-10^38 to 10^38
если вы обеспокоены скоростью, используйте минимальную точность, которая будет длиться всю жизнь вашего программное обеспечение.
если вы не измеряете время в нано-секундах, выберите вариант, который лучше всего подойдет для ваших программистов и вашего желания иметь очень длинный набор чисел.
ссылки