Ouch! Our Data Type Choices Did THAT? G. Vern Rabe RabeData, LLC
Thank You! local PASS Community & Sponsors!
Vern Rabe Independent consultant, trainer MCTA, MCDBA, MCSE, MCITP Co-VP Oregon PASS Chapter Working with/focusing on SQL Server since 1993, starting with SQL Server 4.21a
What We’ll Cover Why do we care? Data type by Data type Performance, accuracy Data type by Data type When to use which Functions and Nuggets What to use, what not to use, some workarounds
Accuracy > Performance > Implicit Conversion (SARGable) > Why Important? Accuracy > Performance > Implicit Conversion (SARGable) >
Implicit Conversion Data Type Precedence user-defined data types (highest) sql_variant xml datetimeoffset datetime2 datetime smalldatetime date time float real decimal money smallmoney bigint int smallint tinyint bit ntext text image rownumber uniqueidentifier nvarchar nchar varchar char varbinary binary (lowest)
Data Type Categories Numeric Character Temporal Binary Other
Numeric Category bit : 0 or 1 tinyint : 0 to 255 smallint : -32,768 to 32,767 int : -2,147,483,648 to 2,147,483,647 bigint : -9,223,372,036,854,775,808 to 9,223,372,036,854,775,808 decimal, numeric : maximum precision of 38 smallmoney : -214,748.3648 to 214,748.3647 money : -922,337,203,685,477.5808 to 922,337,203,685,477.5807 float : approx ± 2 * 10 ±308 real : approx ± 2 * 10 ±38
Numeric Data Type Issues Float/real are imprecise/approximate > Money has (early) rounding surprises > More rounding surprises >
Precision and Scale of Decimal Operation Results Result precision Result scale * e1 + e2 max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2) e1 - e2 e1 * e2 p1 + p2 + 1 s1 + s2 e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1) e1 { UNION | EXCEPT | INTERSECT } e2 max(s1, s2) + max(p1-s1, p2-s2) e1 % e2 min(p1-s1, p2 -s2) + max( s1,s2 ) * The result precision and scale have an absolute maximum of 38. When a result precision is greater than 38, the corresponding scale is reduced to prevent the integral part of a result from being truncated.
Character Category char(N) : 8000 characters nchar(N) : 4000 characters varchar(N) : 8000 characters varchar(MAX) ≈ 2,000,000,000 characters nvarchar(N) : 4000 characters nvarchar(MAX) ≈1,000,000,000 characters) text : ≈ 2,000,000,000 characters ntext : ≈ 1,000,000,000 characters
Character Category char(N) : 8000 characters nchar(N) : 4000 characters varchar(N) : 8000 characters varchar(MAX) ≈ 2,000,000,000 characters nvarchar(N) : 4000 characters nvarchar(MAX) ≈1,000,000,000 characters) text : ≈ 2,000,000,000 characters ntext : ≈ 1,000,000,000 characters
Size Matters (var)char(small) vs. (var)char(big) – difference? > Domain integrity (var)char vs. (var)char(n) > (var)char(n) - When n is not specified in a data definition or variable declaration statement, the default length is 1. When n is not specified with the CAST function, the default length is 30 varchar(n) vs. char(n) varchar(n) vs. varchar(MAX) Performance Rob Garrison blog – http://www.simple-talk.com/sql/database-administration/whats-the-point-of-using-varchar(n)-anymore/
Temporal Category date : 0001-01-01 to 9999-12-31 time : 00:00:00.0000000 to 23:59:59.9999999 datetime2 : 0001-01-01 to 9999-12-31, 100ns precision datetimeoffset : 0001-01-01 to 9999-12-31, 100ns precision smalldatetime : 1900-01-01 to 2079-06-06, precision of 1 minute datetime : 1753-01-01 to 9999-12-31, precision of 3⅓ millisecond (.000, .003, .007, .010 sec)
Temporal Category date : 0001-01-01 to 9999-12-31 time : 00:00:00.0000000 to 23:59:59.9999999 datetime2 : 0001-01-01 to 9999-12-31, 100ns precision datetimeoffset : 0001-01-01 to 9999-12-31, 100ns precision smalldatetime : 1900-01-01 to 2079-06-06, precision of 1 minute datetime : 1753-01-01 to 9999-12-31, precision of ~3⅓ millisecond (.000, .003, .007, .010 sec)
Temporal Examples Date literals > ‘1/2/11’? ‘01-02-2011’? ‘2011-01-02’? 20110102? Using BETWEEN to identify day > Adding days > What date is 0 or ‘’ (empty string)? > Eliminating time from datetime >
Binary Category binary(N) : 8000 bytes varbinary(N) : 8000 bytes varbinary(MAX) ≈ 2,000,000,000 bytes image : ≈ 2,000,000,000 bytes
Binary Category binary(N) : 8000 bytes varbinary(N) : 8000 bytes varbinary(MAX) ≈ 2,000,000,000 bytes image : ≈ 2,000,000,000 bytes
Other Category cursor timestamp/rowversion hierarchyid uniqueidentifier sql_variant xml table
Other Category cursor timestamp/rowversion hierarchyid uniqueidentifier sql_variant xml table
Functions ISNUMERIC > TRY_CONVERT / TRY_CAST > ISDATE > Watch out for empty strings ISDATE > Doesn’t cover entire date range Doesn’t support full resolution of datetime2 CURRENT_TIMESTAMP vs. GETDATE() vs. SYSDATETIME() vs. GETUTCDATE() vs. SYSUTCDATETIME() ISNULL vs. COALESCE > ISNULL returns data type of first argument COALESCE returns data type of highest precedence
Summary Pick data types with consideration Avoid deprecated data types Size matters Domain constraint Avoid deprecated data types Beware of implicit conversions Not SARGable Unexpected results Use functions with caution
Thanks Questions? Contact information vern@rabedata.com @VernRabe LinkedIn www.linkedin.com/pub/vern-rabe/a/ba3/980 References Don’t use datetime or smalldatetime https://msdn.microsoft.com/en-us/library/ms187819.aspx