SQL Server Decimal (9, 0) vs INT

15

Salah satu pelanggan kami menggunakan beberapa kolom tipe data DECIMAL(18,0)dalam database SQL Server 2008R2-nya. Karena kolom tumbuh cukup lambat, dia baru-baru ini mengusulkan untuk mengubah tipe data DECIMAL(5,0)untuk mendapatkan kembali beberapa penyimpanan.

Menurut perpustakaan MSDN , ruang penyimpanan DECIMAL(5,0)tipe data adalah, sama seperti DECIMAL(9,0)tipe data, 5 byte. INTberukuran 1 byte lebih kecil, tetapi dapat menyimpan semuanya dalam kisaran -2 ^ 31 hingga 2 ^ 31 sebagai ganti -99.999 hingga 99.999 yang DECIMAL(5,0)dapat disimpan. Bahkan yang terbesar DECIMALyang masuk ke dalam 5 byte ( DECIMAL(9,0)) dapat menyimpan hanya bilangan bulat dalam kisaran -999.999.999 hingga 999.999.999 (yang kurang dari setengah dari kisaran INTpenawaran dalam 4 byte).

Saya dapat memikirkan dua "manfaat" menggunakan DECIMALlebih dari INT:

  • Kemampuan untuk menambah skala sesudahnya, tanpa menggunakan lebih banyak ruang penyimpanan
  • Kemampuan untuk skala presisi hingga 38 digit, tanpa mengubah tipe data

tapi ini bukan manfaat nyata menurut saya:

  • Menambahkan skala ke bilangan bulat hanya masuk akal dalam beberapa kasus (dalam kebanyakan kasus di mana skala membuat perbedaan, itu juga dapat ditambahkan sebelumnya)
  • SQL Server melihat setiap kombinasi presisi / skala sebagai tipe data yang berbeda, sehingga tipe data tidak dibiarkan sendirian ketika meningkatkan presisi atau skala.

Ini membuat saya bertanya-tanya: apa manfaat tambahan dari DECIMAL(5,0)tipe data untuk bilangan bulat?

vstrien
sumber
1
Satu manfaat bisa menjadi batas lima digit. Tapi saya bertanya-tanya berapa banyak ruang penyimpanan yang dapat Anda simpan dengan perubahan seperti itu.
dezso
3
IMO, jika Anda hanya perlu memastikan nilai kolom berada dalam kisaran, gunakan batasan periksa. Saya pikir satu-satunya pertimbangan di sini adalah jika ada kemungkinan kolom ini membutuhkan nilai fraksional di masa depan.
Jon Seigel
3
Jika mereka khawatir tentang ruang penyimpanan, mereka lebih cocok menggunakan kompresi daripada ini. Tidak ada manfaat nyata untuk menggunakan desimal (x, 0) sebagai ganti int / bigint.
Robert L Davis
7
Perbedaan lain antara decimal(x,0)dan tipe integer menunjukkan dirinya dalam divisi aritmatika. Jika Anda membagi int dengan int, Anda mendapatkan int. Jika Anda membagi desimal (x, 0) dengan int, Anda mendapatkan desimal (x + 6,6).
Andriy M
@ AndriyM, saya pikir ini adalah manfaat terbesar. Ubah kata itu menjadi jawaban alih-alih komentar dan saya akan menandainya sebagai jawaban.
vstrien

Jawaban:

8

Saya setuju bahwa tidak ada manfaat nyata dalam hal ruang penyimpanan selama Anda membandingkan DECIMAL (9, 0) vs INT atau DECIMAL (18, 0) vs BIGINT. (Dalam satu byte.)

Dalam hal pemrosesan, seperti @Andriy mengatakan DECIMAL secara alami akan membagi menjadi jenis yang tidak kehilangan bagian pecahan, jika itu penting bagi Anda.

Di sisi lain, bekerja dengan tipe INT asli jauh lebih cepat dari sudut pandang numerik jika Anda melakukan banyak SUM () atau perbandingan (seperti mencari pada nilai-nilai) karena mereka disalurkan lebih efisien oleh CPU. Perbandingan int adalah dua opcode rakitan (MOV, CMP) tetapi perbandingan desimal akan banyak, banyak lagi.

Chris Chubb
sumber
Jawaban Anda masuk akal, tetapi prosesor tidak memiliki pengetahuan tentang tipe data. Jadi satu tipe data dari 4 byte, dibandingkan secepat tipe data lain dari 4 byte. Bisakah Anda menunjukkan (dengan tes kinerja berulang-ulang, misalnya) bahwa ada hit kinerja dalam menggunakan DECIMAL(9, 0)bukan INT?
vstrien
2
Saya pikir saya bisa, tetapi saya akan mengakui bahwa tes saya tidak meyakinkan. Mungkin SQL sedang melakukan optimasi untuk mengurangi masalah menjadi bilangan bulat matematika. Testbed saya: `--Dalam perbandingan SET @StartTime = SYSDATETIME () WHILE (@CounterINT <@SizeINT) SET @CounterINT = @CounterINT + 1 PRINT 'INT mengambil' + CONVERT (VARCHAR (20), DATEDIFF (milidetik, @StartTime) , SYSDATETIME ())) + 'milidetik' - SET SET @StartTime = SYSDATETIME () SAAT (@CounterDEC <@SizeDEC) SET @CounterDEC = @CounterDEC + 1 CETAK 'DEC take' + CONVERT (VARCHAR (20), DATE) (milidetik, @StartTime, SYSDATETIME ())) + 'milidetik' `
Chris Chubb
Saya pikir SQL Server memang mengoptimalkan sesuatu di sana. Meskipun demikian optimasi DECIMALmasih memakan waktu yang agak lama (setidaknya pada sistem pengembangan saya). Dalam menjalankan 10 tes sekitar 51 ms DEC vs 46 ms INT.
vstrien
2

Sepertinya tidak akan ada manfaat dalam hal ruang penyimpanan.

Jika klien Anda khawatir bahwa nilai Anda akan lebih besar dari 2 ^ 32-1 (integer nilai positif maksimum dapat disimpan) maka Anda harus mempertimbangkan untuk pindah ke BigInt - dengan 64 bit ( 8 byte) .

Alex Pengembang
sumber