Woodinville Reign '97 (14U) Fastpitch
March 24,
2012
2012
declare @variants table ( Value sql_variant, ordinal int identity(1,1) primary key clustered ) insert into @variants ( Value ) select convert( bigint, 4 ) insert into @variants ( Value ) select convert( binary(10), '1234567890' ) insert into @variants ( Value ) select convert( char(10), '1234567890' ) insert into @variants ( Value ) select convert( date, '2012-03-21 01:23:45' ) insert into @variants ( Value ) select convert( datetime, '2012-03-21 01:23:45' ) insert into @variants ( Value ) select convert( datetime2(6), '2012-03-21 01:23:45' ) insert into @variants ( Value ) select convert( datetimeoffset, '2012-03-21 01:23:45' ) insert into @variants ( Value ) select convert( decimal(9,3), 3.45 ) insert into @variants ( Value ) select convert( float, 0.12 ) insert into @variants ( Value ) select convert( int, 0 ) insert into @variants ( Value ) select convert( money, 7.89 ) insert into @variants ( Value ) select convert( nchar(10), '1234567890' ) insert into @variants ( Value ) select convert( numeric, 4.56 ) insert into @variants ( Value ) select convert( nvarchar(10), '1234567890' ) insert into @variants ( Value ) select convert( real, 3 ) insert into @variants ( Value ) select convert( smalldatetime, '2012-03-21 01:23:45' ) insert into @variants ( Value ) select convert( smallint, 2 ) insert into @variants ( Value ) select convert( smallmoney, 0.12 ) insert into @variants ( Value ) select convert( time, '01:23:45' ) insert into @variants ( Value ) select convert( tinyint, 1 ) insert into @variants ( Value ) select convert( uniqueidentifier, newid() ) insert into @variants ( Value ) select convert( varbinary(10), '1234567890' ) insert into @variants ( Value ) select convert( varchar(10), 'varchar(10)' ) select ordinal --,Value ,convert( sysname, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) ,convert( int, SQL_VARIANT_PROPERTY( Value, 'Precision' ) ) ,convert( int, SQL_VARIANT_PROPERTY( Value, 'Scale' ) ) ,convert( int, SQL_VARIANT_PROPERTY( Value, 'TotalBytes' ) ) ,convert( sysname, SQL_VARIANT_PROPERTY( Value, 'Collation' ) ) ,convert( int, SQL_VARIANT_PROPERTY( Value, 'MaxLength' ) ) ,data_definition = case when SQL_VARIANT_PROPERTY(Value,'BaseType') in ('bit', 'tinyint', 'smallint', 'int', 'bigint', 'real', 'smallmoney', 'money','text', 'ntext', 'image', 'date', 'time', 'smalldatetime', 'datetime','timestamp', 'sql_variant', 'xml', 'hierarchyid', 'uniqueidentifier') then convert( nvarchar, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) when SQL_VARIANT_PROPERTY(Value,'BaseType') in ('numeric', 'decimal') then convert( nvarchar, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) + N'(' + convert(nvarchar,SQL_VARIANT_PROPERTY(Value,'Precision')) + N',' + convert(nvarchar,SQL_VARIANT_PROPERTY(Value,'Scale')) + N')' when SQL_VARIANT_PROPERTY(Value,'BaseType') in ('float') then convert( nvarchar, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) + N'(' + convert(nvarchar,SQL_VARIANT_PROPERTY(Value,'Precision')) + N')' when SQL_VARIANT_PROPERTY(Value,'BaseType') in ('char', 'varchar', 'binary', 'varbinary') then convert( nvarchar, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) + N'(' + case when convert( int, SQL_VARIANT_PROPERTY(Value,'MaxLength') ) = -1 then 'max' else convert(nvarchar,SQL_VARIANT_PROPERTY(Value,'MaxLength')) end + N')' when SQL_VARIANT_PROPERTY(Value,'BaseType') in ('nchar', 'nvarchar') then convert( nvarchar, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) + N'(' + case when convert( int, SQL_VARIANT_PROPERTY(Value,'MaxLength') ) = -1 then 'max' else convert(nvarchar,convert(int,SQL_VARIANT_PROPERTY(Value,'MaxLength'))/2) end + N')' when SQL_VARIANT_PROPERTY(Value,'BaseType') in ('datetime2', 'datetimeoffset') then convert( nvarchar, SQL_VARIANT_PROPERTY( Value, 'BaseType' ) ) + case when convert( int, SQL_VARIANT_PROPERTY(Value,'Scale') ) > 0 then N'(' + convert(nvarchar,SQL_VARIANT_PROPERTY(Value,'Scale')) + N')' else N'' end else 'unknown' end from @variants order by ordinal
SELECT o.name AS [Table_Name], x.name AS [Index_Name], i.partition_number AS [Partition], i.index_id AS [Index_ID], x.type_desc AS [Index_Type], i.leaf_update_count * 100.0 / (i.range_scan_count + i.leaf_insert_count + i.leaf_delete_count + i.leaf_update_count + i.leaf_page_merge_count + i.singleton_lookup_count ) AS [Percent_Update] FROM sys.dm_db_index_operational_stats (db_id(), NULL, NULL, NULL) i JOIN sys.objects o ON o.object_id = i.object_id JOIN sys.indexes x ON x.object_id = i.object_id AND x.index_id = i.index_id WHERE (i.range_scan_count + i.leaf_insert_count + i.leaf_delete_count + leaf_update_count + i.leaf_page_merge_count + i.singleton_lookup_count) != 0 AND objectproperty(i.object_id,'IsUserTable') = 1 ORDER BY [Percent_Update] ASC
SELECT o.name AS [Table_Name], x.name AS [Index_Name], i.partition_number AS [Partition], i.index_id AS [Index_ID], x.type_desc AS [Index_Type], i.range_scan_count * 100.0 / (i.range_scan_count + i.leaf_insert_count + i.leaf_delete_count + i.leaf_update_count + i.leaf_page_merge_count + i.singleton_lookup_count ) AS [Percent_Scan] FROM sys.dm_db_index_operational_stats (db_id(), NULL, NULL, NULL) i JOIN sys.objects o ON o.object_id = i.object_id JOIN sys.indexes x ON x.object_id = i.object_id AND x.index_id = i.index_id WHERE (i.range_scan_count + i.leaf_insert_count + i.leaf_delete_count + leaf_update_count + i.leaf_page_merge_count + i.singleton_lookup_count) != 0 AND objectproperty(i.object_id,'IsUserTable') = 1 ORDER BY [Percent_Scan] DESC
Table | Savings ROW % | Savings PAGE % | S | U | Decision | Notes |
---|---|---|---|---|---|---|
T1
|
80%
|
90%
|
3.80%
|
57.27%
|
ROW
|
Low S, very high U. ROW savings close to PAGE
|
T2
|
15%
|
89%
|
92.46%
|
0%
|
PAGE
|
Very high S
|
T3
|
30%
|
81%
|
27.14%
|
4.17%
|
ROW
|
Low S
|
T4
|
38%
|
83%
|
89.16%
|
10.54%
|
ROW
|
High U
|
T5
|
21%
|
87%
|
0.00%
|
0%
|
PAGE
|
Append ONLY table
|
T6
|
28%
|
87%
|
87.54%
|
0%
|
PAGE
|
High S, low U
|
T7
|
29%
|
88%
|
0.50%
|
0%
|
PAGE
|
99% appends
|
T8
|
30%
|
90%
|
11.44%
|
0.06%
|
PAGE
|
85% appends
|
T9
|
84%
|
92%
|
0.02%
|
0.00%
|
ROW
|
ROW savings ~= PAGE
|
T10
|
15%
|
89%
|
100.00%
|
0.00%
|
PAGE
|
Read ONLY table
|
Workspace
|
I/O
|
CPU
| |||||
TEMPDB
|
UserDB
|
UserDB Tran Log
|
TEMPDB
|
UserDB
|
UserDB Tran Log
| ||
OFFLINE with BULK_LOGGED or SIMPLE Recovery Model
| |||||||
Rebuild
|
0
|
X
|
~0
|
0
|
X+2X
|
~0
|
C
|
Compress
|
0
|
P
|
~0
|
0
|
X+2P
|
~0
|
1.5C to 5C
|
OFFLINE with FULL Recovery Model
| |||||||
Rebuild
|
0
|
X
|
X
|
0
|
X+X
|
X
|
~C
|
Compress
|
0
|
P
|
P
|
0
|
X+P
|
P
|
1.5C to 5C
|
ONLINE with FULL Recovery Model
| |||||||
Rebuild
|
M+Y
|
X+Y
|
2X+Y
|
M+4Y
|
X+X+Y
|
2X+Y
|
~2C
|
Compress
|
M+Y
|
P+Y
|
2P+Y
|
M+4Y
|
X+P+Y
|
2P+Y
|
3C to 10C
|
Table organization
|
Table compression setting
| |
ROW
|
PAGE
| |
Heap
|
The newly inserted row is row-compressed.
|
The newly inserted row is page-compressed:
· if new row goes to an existing page with page compression
· if the new row is inserted through BULK INSERT with TABLOCK
· if the new row is inserted through INSERT INTO ... (TABLOCK) SELECT ... FROM
Otherwise, the row is row-compressed.*
|
Clustered index
|
The newly inserted row is row-compressed.
|
The newly inserted row is page-compressed if new row goes to an existing page with page compression Otherwise, it is row compressed until the page fills up. Page compression is attempted before a page split.**
|
Table compression | Transaction log | Mapping index for rebuilding the clustered index | Sort pages for queries | Version store (with SI or RCSI isolation level) |
---|---|---|---|---|
ROW
|
ROW
|
NONE
|
NONE
|
ROW
|
PAGE
|
ROW
|
NONE
|
NONE
|
ROW
|
CREATE UNIQUE CLUSTERED INDEX [PK_TRADE] ON [TRADE_BULK] ([T_ID] ASC) WITH (DATA_COMPRESSION=PAGE, DROP_EXISTING=ON, SORT_IN_TEMPDB=ON) ON [FG_Data2]
-- Create a new empty table in the new filegroup ALTER DATABASE [TestDB] MODIFY FILEGROUP FG_COMP DEFAULT; SELECT * INTO [Tab1] FROM [Tab] WHERE 1 = 2; -- Compress the newly created empty table ALTER TABLE [Tab1] REBUILD WITH (DATA_COMPRESSION = PAGE); -- Create the appropriate indexes on the table -- Copy the data over to the new table INSERT INTO [Tab1] WITH (TABLOCK) SELECT * FROM [Tab] -- The incoming data will be compressed as it gets inserted -- TABLOCK is required if the target table is a heap -- Trace flag 610 may help enable minimal logging -- The LOB_DATA allocation unit will also be copied -- Drop the old table and rename the new table as old table -- After all the tables are copied like this, remove the old filegroup
Compression setting of the destination partition | What happens to the data moving in from the source to the destination partition |
---|---|
NONE
|
The incoming data is decompressed during merge
|
ROW
|
The incoming data is row-compressed during merge
|
PAGE
|
- Heap: The incoming data is row-compressed during merge
- Clustered index: The incoming data is page-compressed during merge
|
-- Provided AS IS, without warranty of any kind SELECT OBJECT_NAME(p.object_id) AS Object_Name , i.name AS Index_Name , ps.in_row_used_page_count AS IN_ROW_DATA , ps.row_overflow_used_page_count AS ROW_OVERFLOW_DATA , ps.lob_used_page_count AS LOB_DATA FROM sys.dm_db_partition_stats ps JOIN sys.partitions p ON ps.partition_id = p.partition_id JOIN sys.indexes i ON p.index_id = i.index_id AND p.object_id = i.object_id WHERE OBJECTPROPERTY (p.[object_id], 'IsUserTable') = 1
--Provided AS IS, without warranty of any kind SELECT a.file_id, LOGICAL_NAME = a.name, PHYSICAL_FILENAME = a.physical_name, FILEGROUP_NAME = b.name, FILE_SIZE_MB = CONVERT(DECIMAL(12,2),ROUND(a.size/128.000,2)), SPACE_USED_MB = CONVERT(DECIMAL(12,2),ROUND(FILEPROPERTY(a.name,'SpaceUsed')/128.000,2)), FREE_SPACE_MB = CONVERT(DECIMAL(12,2),ROUND((a.size-FILEPROPERTY(a.name,'SpaceUsed'))/128.000,2)) FROM sys.database_files a LEFT OUTER JOIN sys.data_spaces b ON a.data_space_id = b.data_space_id
SELECT o.name, ips.index_type_desc, p.partition_number, p.data_compression_desc, ips.index_level, ips.page_count, ips.compressed_page_count FROM sys.dm_db_index_physical_stats (DB_ID(), object_id(<insert index name here>), NULL, NULL, 'DETAILED') ips JOIN sys.objects o ON o.object_id = ips.object_id JOIN sys.partitions p ON p.object_id = o.object_id ORDER BY ips.index_level
Name | index_type_desc | partition_number | data_compression_desc | index_level | page_count | compressed_page_count |
---|---|---|---|---|---|---|
TRADE_BULK
|
CLUSTERED INDEX
|
1
|
PAGE
|
0
|
370508
|
370502
|
TRADE_BULK
|
CLUSTERED INDEX
|
1
|
PAGE
|
1
|
830
|
0
|
TRADE_BULK
|
CLUSTERED INDEX
|
1
|
PAGE
|
2
|
5
|
0
|
TRADE_BULK
|
CLUSTERED INDEX
|
1
|
PAGE
|
3
|
1
|
0
|
SELECT o.name, ips.index_type_desc, p.partition_number, p.data_compression_desc, ips.page_count, ips.compressed_page_count FROM sys.dm_db_index_physical_stats (DB_ID(), object_id(<insert table name here>), NULL, NULL, 'DETAILED') ips JOIN sys.objects o ON o.object_id = ips.object_id JOIN sys.partitions p ON p.object_id = o.object_id
name | index_type_desc | partition_number | data_compression_desc | page_count | compressed_page_count |
---|---|---|---|---|---|
TRADE_BULK
|
HEAP
|
1
|
PAGE
|
501574
|
0
|
name | index_type_desc | partition_number | data_compression_desc | page_count | compressed_page_count |
---|---|---|---|---|---|
TRADE_BULK
|
HEAP
|
1
|
PAGE
|
370658
|
370656
|
of or pertaining to the period in which a fisherman must leave to go fishing. |
of or pertaining to applications in which the computer must respond as rapidly as required by the user or necessitated by the process being controlled. |