Десятичний розмір SQL Server (9, 0) проти INT


15

Один з наших клієнтів використовує для деяких стовпців тип даних DECIMAL(18,0)у своїй базі даних SQL Server 2008R2. Оскільки стовпці ростуть досить повільно, він нещодавно запропонував змінити тип даних, DECIMAL(5,0)щоб відновити деякий обсяг пам’яті.

За даними бібліотеки MSDN , місце зберігання DECIMAL(5,0)типу даних становить, як і DECIMAL(9,0)тип даних, 5 байт. INTна 1 байт менше, але може зберігати все в діапазоні від -2 ^ 31 до 2 ^ 31 замість від -99,999 до 99,999, яке DECIMAL(5,0)може зберігатись. Навіть найбільший, DECIMALякий вміщується в 5 байт ( DECIMAL(9,0)), може зберігати лише цілі числа в діапазоні від -999,999,999 до 999,999,999 (що менше половини пропонованого діапазону INTв 4 байти).

Я можу придумати дві "переваги" використання DECIMALнад INT:

  • Можливість додавати масштаб згодом, не використовуючи більше місця для зберігання
  • Можливість масштабування точності до 38 цифр, не змінюючи тип даних

але, на мою думку, це не реальна користь:

  • Додавання шкали до цілих чисел має сенс лише у дуже небагатьох випадках (у більшості випадків, коли масштаб має значення, він також може бути доданий заздалегідь)
  • SQL Server розглядає кожну комбінацію точності / масштабу як різний тип даних, тому тип даних не залишається у спокої при збільшенні точності або масштабу.

Це змушує мене замислитися: яка додаткова перевага DECIMAL(5,0)типу даних для цілих чисел?


1
Однією перевагою може бути п'ятизначна межа. Але мені цікаво, скільки місця для зберігання можна заощадити при такій зміні.
dezso

3
IMO, якщо вам просто потрібно переконатися, що значення стовпців потрапляють у діапазон, використовуйте контрольне обмеження. Я думаю, що тут розглядатиметься лише те, чи існує можливість цього стовпця вимагати дробових значень у майбутньому.
Джон Сейгель

3
Якщо вони турбуються про місце для зберігання, вони краще підходять для стиснення, ніж це. Немає відчутної переваги використовувати десятковий (x, 0) замість int / bigint.
Роберт Л Девіс

7
Ще одна відмінність між decimal(x,0)цілим числом проявляється в арифметичному поділі. Якщо ви поділите інт на інт, ви отримаєте інт. Якщо розділити десятковий (x, 0) на int, ви отримаєте десятковий (x + 6,6).
Андрій М

@AndriyM, я думаю, що це найбільша користь. Перефразовуйте його у відповідь замість коментаря, і я позначу це як відповідь.
vstrien

Відповіді:


8

Я погоджуюся, що реальних переваг щодо місця для зберігання даних немає , якщо ви порівнюєте DECIMAL (9, 0) проти INT або DECIMAL (18, 0) і BIGINT. (В межах одного байта.)

Що стосується обробки, як @Andriy каже, DECIMAL природно розділиться на тип, який не втратить дробову частину, якщо це важливо для вас.

З іншого боку, робота з натурними типами INT значно швидша з чисельної точки зору, якщо ви робите багато SUM (s) або порівнянь (таких як пошук значень), оскільки вони ефективніше конфігуруються процесором. Інт-порівняння - це два опкоди складання (MOV, CMP), але будь-яке десяткове порівняння буде багато-багато іншого.


Ваша відповідь має сенс, але процесор не має знань про типи даних. Таким чином, один тип даних у 4 байти порівнюється так само швидко, як і інший тип даних у 4 байти. Чи можете ви показати (наприклад, з повторюваним тестом на ефективність), що використовується показник ефективності DECIMAL(9, 0)замість INT?
vstrien

2
Я думав, що зможу, але визнаю, що мої тести є непереконливими. Можливо, SQL робить оптимізацію для зменшення проблеми до цілої математики. Мій тестовий аркуш: `--Порівняння SET @StartTime = SYSDATETIME () WHILE (@CounterINT <@SizeINT) SET @CounterINT = @CounterINT + 1 PRINT 'INT взяв' + CONVERT (VARCHAR (20), DATEDIFF (мілісекунда, @StartTime , SYSDATETIME ())) + 'мілісекунди' - Десетичний SET @StartTime = SYSDATETIME () ВІД (@CounterDEC <@SizeDEC) SET @CounterDEC = @CounterDEC + 1 PRINT 'DEC взяв' + CONVERT (VARCHAR (20), DATEDIF (мілісекунда, @StartTime, SYSDATETIME ())) + 'мілісекунд' '
Кріс Чубб

Я думаю, що SQL Server дійсно щось там оптимізує. Незважаючи на оптимізацію, DECIMALвсе ще потрібно дещо довше (принаймні, в моїй системі розвитку). Пробіг 10 тестів близько 51 мс DEC проти 46 мс INT.
vstrien

2

Схоже , ніяких переваг у плані місця для зберігання не буде.

Якщо ваш клієнт стурбований тим, що ваші значення будуть перевищувати 2 ^ 32-1 (максимальне додатне значення може зберігати ціле число), тоді вам слід розглянути можливість переходу до BigInt - з 64 бітами ( 8 байт) .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.