/
ch15.sql
412 lines (341 loc) · 10.5 KB
/
ch15.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
-- 15-0 - Chapter setup of files and filegroups
USE master;
GO
IF db_id('MegaCorpData') IS NOT NULL DROP DATABASE MegaCorpData;
GO
CREATE DATABASE MegaCorpData
ON PRIMARY
(NAME = 'MegaCorpData',
FILENAME = 'C:\Apress\MegaCorpData.MDF',
SIZE = 3MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 1MB)
LOG ON
(NAME = 'MegaCorpData_Log',
FILENAME = 'C:\Apress\MegaCorpData.LDF',
SIZE = 3MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 1MB);
GO
-- 15-1. Partitioning a Table
USE master;
GO
ALTER DATABASE MegaCorpData ADD FILEGROUP hitfg1;
ALTER DATABASE MegaCorpData ADD FILEGROUP hitfg2;
ALTER DATABASE MegaCorpData ADD FILEGROUP hitfg3;
ALTER DATABASE MegaCorpData ADD FILEGROUP hitfg4;
GO
ALTER DATABASE MegaCorpData
ADD FILE (NAME = mchitfg1,
FILENAME = 'C:\Apress\mc_hitfg1.ndf',
SIZE = 1MB)
TO FILEGROUP hitfg1;
ALTER DATABASE MegaCorpData
ADD FILE (NAME = mchitfg2,
FILENAME = 'C:\Apress\mc_hitfg2.ndf',
SIZE = 1MB)
TO FILEGROUP hitfg2;
ALTER DATABASE MegaCorpData
ADD FILE (NAME = mchitfg3,
FILENAME = 'C:\Apress\mc_hitfg3.ndf',
SIZE = 1MB)
TO FILEGROUP hitfg3;
ALTER DATABASE MegaCorpData
ADD FILE (NAME = mchitfg4,
FILENAME = 'C:\Apress\mc_hitfg4.ndf',
SIZE = 1MB)
TO FILEGROUP hitfg4;
GO
USE MegaCorpData;
GO
CREATE PARTITION FUNCTION HitsDateRange (datetime)
AS RANGE LEFT FOR VALUES ('2006-01-01', '2007-01-01', '2008-01-01');
GO
CREATE PARTITION SCHEME HitDateRangeScheme
AS PARTITION HitsDateRange
TO (hitfg1, hitfg2, hitfg3, hitfg4);
CREATE TABLE dbo.WebSiteHits (
WebSiteHitID BIGINT NOT NULL IDENTITY(1, 1),
WebSitePage VARCHAR(255) NOT NULL,
HitDate DATETIME NOT NULL,
CONSTRAINT PK_WebSiteHits PRIMARY KEY CLUSTERED (WebSiteHitId, HitDate)
)
ON [HitDateRangeScheme] (HitDate);
-- 15-2. Locating Data in a Partition
USE MegaCorpData;
GO
TRUNCATE TABLE dbo.WebSiteHits;
INSERT dbo.WebSiteHits (WebSitePage, HitDate)
VALUES ('Home Page', '2007-10-22'),
('Home Page', '2006-10-02'),
('Sales Page', '2008-05-09'),
('Sales Page', '2000-03-04');
SELECT WebSitePage,
HitDate,
$PARTITION.HitsDateRange (HitDate) AS [Partition]
FROM dbo.WebSiteHits;
-- 15-3. Adding a Partition
USE MegaCorpData;
GO
ALTER PARTITION SCHEME HitDateRangeScheme NEXT USED [PRIMARY];
GO
ALTER PARTITION FUNCTION HitsDateRange () SPLIT RANGE ('2009-01-01');
GO
INSERT dbo.WebSiteHits
(WebSitePage, HitDate)
VALUES ('Sales Page', '2009-03-04');
SELECT WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHits;
-- 15-4. Removing a Partition
USE MegaCorpData;
GO
ALTER PARTITION FUNCTION HitsDateRange () MERGE RANGE ('2007-01-01');
GO
SELECT WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHits;
-- 15-5. Determining Whether a Table Is Partitioned
USE MegaCorpData;
GO
SELECT p.partition_id,
p.object_id,
p.partition_number
FROM sys.partitions AS p
WHERE p.partition_id IS NOT NULL
AND p.object_id = OBJECT_ID('dbo.WebSiteHits');
-- 15-6. Determining the Boundary Values for a Partitioned Table
USE MegaCorpData;
GO
SELECT t.name AS TableName,
i.name AS IndexName,
p.partition_number AS [Partition#],
--p.partition_id,
--i.data_space_id,
--f.function_id,
f.type_desc,
CASE WHEN f.boundary_value_on_right = 1 THEN 'RIGHT' ELSE 'LEFT' END AS BoundaryType,
r.boundary_id,
r.value AS BoundaryValue
FROM sys.tables AS t
JOIN sys.indexes AS i
ON t.object_id = i.object_id
JOIN sys.partitions AS p
ON i.object_id = p.object_id
AND i.index_id = p.index_id
JOIN sys.partition_schemes AS s
ON i.data_space_id = s.data_space_id
JOIN sys.partition_functions AS f
ON s.function_id = f.function_id
LEFT JOIN sys.partition_range_values AS r
ON f.function_id = r.function_id
AND r.boundary_id = p.partition_number
WHERE t.object_id = OBJECT_ID('dbo.WebSiteHits')
AND i.type <= 1
ORDER BY p.partition_number;
-- 15-7. Determining the Partitioning Column for a Partitioned Table
USE MegaCorpData;
GO
SELECT t.object_id AS Object_ID,
t.name AS TableName,
ic.column_id AS PartitioningColumnID,
c.name AS PartitioningColumnName
FROM sys.tables AS t
JOIN sys.indexes AS i
ON t.object_id = i.object_id
JOIN sys.partition_schemes AS ps
ON ps.data_space_id = i.data_space_id
JOIN sys.index_columns AS ic
ON ic.object_id = i.object_id
AND ic.index_id = i.index_id
AND ic.partition_ordinal > 0
JOIN sys.columns AS c
ON t.object_id = c.object_id
AND ic.column_id = c.column_id
WHERE t.object_id = OBJECT_ID('dbo.WebSiteHits')
AND i.type <= 1;
-- 15-8. Moving a Partition to a Different Partitioned Table
USE MegaCorpData;
GO
CREATE TABLE dbo.WebSiteHitsHistory
(
WebSiteHitID BIGINT NOT NULL IDENTITY,
WebSitePage VARCHAR(255) NOT NULL,
HitDate DATETIME NOT NULL,
CONSTRAINT PK_WebSiteHitsHistory PRIMARY KEY (WebSiteHitID, HitDate)
)
ON [HitDateRangeScheme](HitDate);
GO
-- move partition 1 to partition 1 of another partitioned table
ALTER TABLE dbo.WebSiteHits SWITCH PARTITION 1 TO dbo.WebSiteHitsHistory PARTITION 1;
GO
SELECT WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHits;
SELECT WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHitsHistory;
-- 15-9. Moving Data from a Nonpartitioned Table to a Partition in a Partitioned Table
USE MegaCorpData;
GO
-- move data from a non-partitioned table to a partitioned table.
IF OBJECT_ID('dbo.WebSiteHitsImport','U') IS NOT NULL DROP TABLE dbo.WebSiteHitsImport;
GO
CREATE TABLE dbo.WebSiteHitsImport
(
WebSiteHitID BIGINT NOT NULL IDENTITY,
WebSitePage VARCHAR(255) NOT NULL,
HitDate DATETIME NOT NULL,
CONSTRAINT PK_WebSiteHitsImport PRIMARY KEY (WebSiteHitID, HitDate),
CONSTRAINT CK_WebSiteHitsImport CHECK (HitDate <= '2006-01-01')
)
ON hitfg1;
GO
INSERT INTO dbo.WebSiteHitsImport (WebSitePage, HitDate)
VALUES ('Sales Page', '2005-06-01'),
('Main Page', '2005-06-01');
GO
-- partition 1 is empty - move data to this partition
ALTER TABLE dbo.WebSiteHitsImport SWITCH TO dbo.WebSiteHits PARTITION 1;
GO
-- see the data
SELECT WebSiteHitId,
WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHits;
SELECT WebSiteHitId,
WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHitsImport;
-- 15-10. Moving a Partition from a Partitioned Table to a Nonpartitioned Table
USE MegaCorpData;
GO
-- move data from a non-partitioned table to a partitioned table.
ALTER TABLE dbo.WebSiteHits SWITCH PARTITION 1 TO dbo.WebSiteHitsImport;
GO
-- see the data
SELECT WebSiteHitId,
WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHits;
SELECT WebSiteHitId,
WebSitePage,
HitDate,
$PARTITION.HitsDateRange(HitDate) Partition
FROM dbo.WebSiteHitsImport;
-- 15-11. Reducing Table Locks on Partitioned Tables
USE MegaCorpData;
GO
ALTER TABLE dbo.WebSiteHits SET (LOCK_ESCALATION = AUTO);
GO
-- 15-12. Removing Partition Functions and Schemes
USE MegaCorpData;
GO
DROP TABLE dbo.WebSiteHits;
DROP TABLE dbo.WebSiteHitsHistory;
DROP PARTITION SCHEME HitDateRangeScheme;
DROP PARTITION FUNCTION HitsDateRange;
GO
-- 15-14. Compressing Table Data
USE MegaCorpData;
GO
IF OBJECT_ID('dbo.DataCompressionTest','U') IS NOT NULL DROP TABLE dbo.DataCompressionTest;
GO
CREATE TABLE dbo.DataCompressionTest
(
JobPostinglD INT NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
CandidatelD INT NOT NULL,
JobDESC CHAR(2000) NOT NULL
)
WITH (DATA_COMPRESSION = ROW);
GO
IF OBJECT_ID('dbo.ArchiveJobPosting','U') IS NOT NULL DROP TABLE dbo.ArchiveJobPosting;
GO
CREATE TABLE dbo.ArchiveJobPosting
(
JobPostinglD INT NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
CandidatelD INT NOT NULL,
JobDESC CHAR(2000) NOT NULL
);
GO
INSERT dbo.ArchiveJobPosting
(CandidatelD,
JobDESC)
VALUES (CAST(RAND() * 10 AS INT),
REPLICATE('a', 50))
GO 100000
EXECUTE sp_estimate_data_compression_savings @schema_name = 'dbo', @object_name = 'ArchiveJobPosting', @index_id = NULL, @partition_number = NULL, @data_compression = 'ROW';
GO
EXECUTE sp_estimate_data_compression_savings @schema_name = 'dbo', @object_name = 'ArchiveJobPosting', @index_id = NULL, @partition_number = NULL, @data_compression = 'PAGE';
GO
ALTER TABLE dbo.ArchiveJobPosting REBUILD WITH (DATA_COMPRESSION = PAGE);
GO
CREATE PARTITION FUNCTION pfn_ArchivePart(int)
AS RANGE LEFT FOR VALUES (50000, 100000, 150000);
GO
CREATE PARTITION SCHEME psc_ArchivePart
AS PARTITION pfn_ArchivePart
TO (hitfg1, hitfg2, hitfg3, hitfg4);
GO
CREATE TABLE dbo.ArchiveJobPosting_V2
(
JobPostingID INT NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
CandidateID INT NOT NULL,
JobDesc CHAR(2000) NOT NULL
)
ON psc_ArchivePart(JobPostingID)
WITH (
DATA_COMPRESSION = PAGE ON PARTITIONS (1 TO 3),
DATA_COMPRESSION = ROW ON PARTITIONS (4));
GO
ALTER TABLE dbo.ArchiveJobPosting_V2
REBUILD PARTITION = 4
WITH (DATA_COMPRESSION = PAGE);
GO
-- 15-15. Rebuilding a Heap
USE MegaCorpData;
GO
IF OBJECT_ID('dbo.HeapTest','U') IS NOT NULL DROP TABLE dbo.HeapTest;
GO
CREATE TABLE dbo.HeapTest
(
HeapTest VARCHAR(1000)
);
GO
INSERT INTO dbo.HeapTest (HeapTest)
VALUES ('Test');
GO 10000
SELECT index_type_desc,
fragment_count,
page_count,
forwarded_record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), DEFAULT, DEFAULT, DEFAULT, 'DETAILED')
WHERE object_id = OBJECT_ID('HeapTest');
GO
UPDATE dbo.HeapTest
SET HeapTest = REPLICATE('Test',250);
GO
SELECT index_type_desc,
fragment_count,
page_count,
forwarded_record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), DEFAULT, DEFAULT, DEFAULT, 'DETAILED')
WHERE object_id = OBJECT_ID('HeapTest');
GO
ALTER TABLE dbo.HeapTest REBUILD;
GO
SELECT index_type_desc,
fragment_count,
page_count,
forwarded_record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), DEFAULT, DEFAULT, DEFAULT, 'DETAILED')
WHERE object_id = OBJECT_ID('HeapTest');
GO