|
| 1 | +/* |
| 2 | +<documentation> |
| 3 | + <summary>Find SQL Server Integer Columns to Make Skinnier</summary> |
| 4 | + <returns>1 data set: temp table #errlog.</returns> |
| 5 | + <issues>No</issues> |
| 6 | + <author>Konstantin Taranov</author> |
| 7 | + <created>2019-07-25</created> |
| 8 | + <modified>2019-08-14 by Konstantin Taranov</modified> |
| 9 | + <version>1.0</version> |
| 10 | + <sourceLink>https://github.com/ktaranov/sqlserver-kit/blob/master/Scripts/Find_SQL_Server_Integer_Columns_to_Make_Skinnier.sql</sourceLink> |
| 11 | + <originalLink>https://www.mssqltips.com/sqlservertip/6107/find-sql-server-integer-columns-to-make-skinnier/</originalLink> |
| 12 | +</documentation> |
| 13 | +*/ |
| 14 | + |
| 15 | +SET NOCOUNT ON; |
| 16 | + |
| 17 | +IF OBJECT_ID(N'dbo.floob', 'U') IS NOT NULL DROP TABLE dbo.floob; |
| 18 | +IF OBJECT_ID(N'dbo.mort', 'U') IS NOT NULL DROP TABLE dbo.mort; |
| 19 | + |
| 20 | +CREATE TABLE dbo.floob(x bigint, y int, z smallint); |
| 21 | +INSERT dbo.floob(x,y,z) VALUES(1,1,1),(32766,32766,254); |
| 22 | +CREATE TABLE dbo.mort(a int, b tinyint); |
| 23 | +INSERT dbo.mort(a,b) VALUES(1,1),(32768,254); |
| 24 | + |
| 25 | +IF OBJECT_ID(N'tempdb..#cols', 'U') IS NOT NULL DROP TABLE #cols; |
| 26 | + |
| 27 | +DECLARE @src bigint = 2; |
| 28 | +;WITH types AS |
| 29 | +( |
| 30 | + SELECT * FROM |
| 31 | + (VALUES |
| 32 | + (1,0,1, 104, N'bit', 1, 0, 1), |
| 33 | + (2,1,1, 48, N'tinyint', 1, 0, 255), |
| 34 | + (3,1,1, 52, N'smallint', 2, -(POWER(@src,15)), (POWER(@src,15)-1)), |
| 35 | + (4,1,1, 56, N'int', 4, -(POWER(@src,31)), (POWER(@src,31)-1)), |
| 36 | + (5,1,0, 127, N'bigint', 8, -(POWER(@src,62)-1)*2-2, (POWER(@src,62)-1)*2+1) |
| 37 | + ) AS v(seq,src,trg,type_id,[type],bytes,minval,maxval) |
| 38 | +), |
| 39 | +cols AS |
| 40 | +( |
| 41 | + SELECT t.[object_id], |
| 42 | + [schema] = s.name, |
| 43 | + [table] = t.name, |
| 44 | + [column] = QUOTENAME(c.name), |
| 45 | + [type] = styp.name + COALESCE(' (alias: ' + utyp.name + ')', ''), |
| 46 | + c.is_nullable, |
| 47 | + trgtyp.seq, |
| 48 | + trgtyp.type_id, |
| 49 | + trgtype = trgtyp.[type], |
| 50 | + savings = srctyp.bytes - trgtyp.bytes, |
| 51 | + trgtyp.minval, |
| 52 | + trgtyp.maxval, |
| 53 | + [rowcount] = (SELECT SUM([rows]) FROM sys.partitions |
| 54 | + WHERE object_id = t.object_id AND index_id IN (0,1)) |
| 55 | + FROM sys.tables AS t |
| 56 | + INNER JOIN sys.schemas AS s |
| 57 | + ON s.[schema_id] = t.[schema_id] |
| 58 | + INNER JOIN sys.columns AS c |
| 59 | + ON t.[object_id] = c.[object_id] |
| 60 | + INNER JOIN sys.types AS styp |
| 61 | + ON c.system_type_id = styp.system_type_id |
| 62 | + AND c.system_type_id = styp.user_type_id |
| 63 | + LEFT OUTER JOIN sys.types AS utyp |
| 64 | + ON c.user_type_id = utyp.user_type_id |
| 65 | + AND utyp.user_type_id <> utyp.system_type_id |
| 66 | + INNER JOIN types AS srctyp |
| 67 | + ON srctyp.type_id = c.system_type_id |
| 68 | + INNER JOIN types AS trgtyp |
| 69 | + ON trgtyp.seq < srctyp.seq |
| 70 | + WHERE srctyp.src = 1 |
| 71 | + AND trgtyp.trg = 1 |
| 72 | +) |
| 73 | +SELECT * INTO #cols FROM cols; |
| 74 | + |
| 75 | +DECLARE @sql nvarchar(max) = N';WITH x([object_id], [column], minval, maxval) |
| 76 | +AS (', |
| 77 | + @core nvarchar(max) = N' |
| 78 | + SELECT $oid, ''$c'', MIN($c), MAX($c) FROM $obj UNION ALL'; |
| 79 | +SELECT @sql += REPLACE(REPLACE(REPLACE(@core, '$oid', RTRIM(object_id)), |
| 80 | + '$c',[column]),'$obj',QUOTENAME([schema]) + '.' + QUOTENAME([table])) |
| 81 | + FROM (SELECT [schema],[table],[column],object_id FROM #cols |
| 82 | + GROUP BY [schema],[table],[column],object_id) AS x; |
| 83 | +SET @sql += N' |
| 84 | + SELECT NULL,NULL,NULL,NULL |
| 85 | + ) |
| 86 | + SELECT c.[schema], c.[table], c.[column], c.is_nullable, |
| 87 | + current_type = c.[type], potential_type = c.trgtype, |
| 88 | + space_savings = c.savings * c.[rowcount], x.minval, x.maxval, |
| 89 | + range = RTRIM(c.minval) + '' -> '' + RTRIM(c.maxval) |
| 90 | + FROM x |
| 91 | + INNER JOIN #cols AS c |
| 92 | + ON x.[object_id] = c.[object_id] |
| 93 | + AND x.[column] = c.[column] |
| 94 | + AND x.minval >= c.minval |
| 95 | + AND x.maxval <= c.maxval;'; |
| 96 | + |
| 97 | +--PRINT(@sql); |
| 98 | + |
| 99 | +EXEC sys.sp_executesql @sql; |
0 commit comments