-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathExpandBabbyNames_Partitioning.sql
executable file
·417 lines (319 loc) · 11.3 KB
/
ExpandBabbyNames_Partitioning.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
413
414
415
416
417
/*****************************************************************************
Copyright (c) 2017 SQL Workbooks LLC
Terms of Use: https://sqlworkbooks.com/terms-of-service/
Contact: help@sqlworkbooks.com
This script:
Is only suitable for test environments
Restores and modifies data in BabbyNames
Creates and loads large tables
Note: this script assumes you have a backup of BabbyNames
at 'S:\MSSQL\Backup\BabbyNames.bak'
You need to either change that, or put a backup there :)
****************************************/
/****************************************************
Take a backup of this expanded database after running the setup script,
so you can just restore it in the future instead of re-running setup
****************************************************/
/*
--BACKUP DATABASE BabbyNames
-- TO DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_1_of_4.bak',
-- DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_2_of_4.bak',
-- DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_3_of_4.bak',
-- DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_4_of_4.bak'
-- WITH COMPRESSION, INIT;
--GO
use master;
GO
IF DB_ID('BabbyNames') IS NOT NULL
BEGIN
ALTER DATABASE BabbyNames SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
END
GO
RESTORE DATABASE BabbyNames FROM
DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_1_of_4.bak',
DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_2_of_4.bak',
DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_3_of_4.bak',
DISK = N'S:\MSSQL\Backup\BabbyNames_Partitioning_4_of_4.bak'
WITH REPLACE;
GO
*/
/****************************************************
Restore Small BabbyNames database with prejudice
****************************************************/
SET STATISTICS IO, TIME OFF;
GO
SET NOCOUNT ON;
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
use master;
GO
IF DB_ID('BabbyNames') IS NOT NULL
BEGIN
ALTER DATABASE BabbyNames
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
END
GO
RESTORE DATABASE BabbyNames
FROM DISK=N'S:\MSSQL\Backup\BabbyNames.bak'
WITH
MOVE 'BabbyNames' TO 'S:\MSSQL\Data\BabbyNames.mdf',
MOVE 'BabbyNames_log' TO 'S:\MSSQL\Data\BabbyNames_log.ldf',
REPLACE,
RECOVERY;
GO
ALTER DATABASE BabbyNames SET RECOVERY SIMPLE;
GO
/* SQL Server 2014+ */
ALTER DATABASE BabbyNames SET COMPATIBILITY_LEVEL=130;
GO
/* SQL Server 2012+ */
ALTER DATABASE BabbyNames SET TARGET_RECOVERY_TIME = 60 SECONDS;
GO
USE BabbyNames;
GO
EXEC evt.logme N'Restored database. Let the games begin.';
GO
/* SQL Server 2016+ */
ALTER DATABASE SCOPED CONFIGURATION SET QUERY_OPTIMIZER_HOTFIXES = ON;
GO
ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = OFF;
GO
exec sp_configure 'show advanced options', 1;
GO
RECONFIGURE
GO
exec sp_configure 'max degree of parallelism', 4;
GO
RECONFIGURE
GO
/* This script expands the data a couple of times. */
ALTER DATABASE BabbyNames MODIFY FILE (NAME='BabbyNames', SIZE=10GB);
GO
ALTER DATABASE BabbyNames MODIFY FILE (NAME='BabbyNames_log', SIZE=3GB);
GO
/******************************************************/
/* FILEGROUPS */
/******************************************************/
EXEC evt.logme N'ADD FILEGROUP fg_FirstNameByBirthDate_pt;';
GO
ALTER DATABASE BabbyNames
ADD FILEGROUP fg_FirstNameByBirthDate_pt;
GO
EXEC evt.logme N'ADD FILE fg_FirstNameByBirthDate_pt_1;';
GO
ALTER DATABASE BabbyNames
ADD FILE
(
NAME = fg_FirstNameByBirthDate_pt_1,
/* Change Location 1 of 2 */
FILENAME = 'S:\MSSQL\Data\BabbyNames_fg_FirstNameByBirthDate_pt_1.ndf',
SIZE = 10GB,
MAXSIZE = 20GB,
FILEGROWTH = 512MB
) TO FILEGROUP fg_FirstNameByBirthDate_pt;
GO
ALTER DATABASE BabbyNames SET DELAYED_DURABILITY = FORCED;
GO
/******************************************************/
/* ref.Numbers */
/******************************************************/
/* Create ref.Numbers. This is a helper "numbers" table just to help us in the next step.*/
IF SCHEMA_ID('ref') IS NULL
BEGIN
EXEC evt.logme N'Create schema ref.';
EXEC ('CREATE SCHEMA ref AUTHORIZATION dbo');
END
GO
EXEC evt.logme N'Create ref.Numbers.';
GO
IF OBJECT_ID('ref.Numbers','U') IS NOT NULL
BEGIN
EXEC evt.logme N'Table ref.Numbers already exists, dropping.';
DROP TABLE ref.Numbers;
END
GO
CREATE TABLE ref.Numbers (
Num INT NOT NULL,
);
GO
EXEC evt.logme N'Load ref.Numbers.';
GO
INSERT ref.Numbers WITH (TABLOCK)
(Num)
SELECT TOP 10000000
ROW_NUMBER() OVER (ORDER BY fn1.ReportYear)
FROM agg.FirstNameByYear AS fn1
CROSS JOIN agg.FirstNameByYear AS fn2;
GO
EXEC evt.logme N'Key ref.Numbers.';
GO
ALTER TABLE ref.Numbers
ADD CONSTRAINT pk_refNumbers_Num
PRIMARY KEY CLUSTERED (Num);
GO
/******************************************************/
/* dbo.loaddetail */
/******************************************************/
IF OBJECT_ID('dbo.loaddetail') IS NULL
EXEC ('CREATE PROCEDURE dbo.loaddetail AS RETURN 0');
GO
ALTER PROCEDURE dbo.loaddetail
@min INT /* we've got data since 1880*/,
@max INT,
@schema NVARCHAR(3) = N'dbo'
AS
DECLARE @msg NVARCHAR(512);
DECLARE @tablename NVARCHAR(256);
DECLARE @dsql NVARCHAR(MAX);
SET @tablename = @schema + N'.FirstNameByBirthDate_' + CAST(@min as NVARCHAR(4)) + '_' + CAST(@max as NVARCHAR(4));
DECLARE @increment INT;
SET @increment=@min;
SET @msg = N'Creating table ' + @tablename + N'.';
EXEC evt.logme @msg;
IF OBJECT_ID(@tablename,'U') IS NOT NULL
BEGIN
SET @msg= N'Table ' + @tablename + N' already exists, dropping.';
EXEC evt.logme @msg;
SET @dsql= N'DROP TABLE ' + @tablename + N';'
EXEC (@dsql);
END
SET @dsql = N'
CREATE TABLE ' + @tablename + N' (
FakeBirthDateStamp DATETIME2(0),
FirstNameByBirthDateId BIGINT IDENTITY NOT NULL,
BirthYear AS YEAR(FakeBirthDateStamp) PERSISTED NOT NULL ,
StateCode CHAR(2) NOT NULL,
FirstNameId INT NOT NULL,
Gender CHAR(1) NOT NULL
);'
EXEC (@dsql);
WHILE @increment <= @max
BEGIN
SET @msg = N'Inserting into ' + @tablename + ' for year ' + cast(@increment as nvarchar(4)) + N'.';
EXEC evt.logme @msg;
SET @dsql=N'
INSERT '+ @tablename + ' WITH (TABLOCK)
(FakeBirthDateStamp, StateCode, FirstNameId, Gender
)
SELECT
DATEADD(mi,num.Num * 5.1,CAST(''1/1/'' + CAST(fn.ReportYear AS CHAR(4)) AS DATETIME2(0))) as FakeBirthDateStamp,
fn.StateCode,
fn.FirstNameId,
fn.Gender
FROM agg.FirstNameByYearState AS fn
RIGHT OUTER JOIN ref.Numbers num on
num.Num <= fn.NameCount
WHERE fn.ReportYear = ' + CAST(@increment AS NCHAR(4)) + N'
ORDER BY FakeBirthDateStamp
OPTION (RECOMPILE);'
EXEC sp_executesql @dsql;
SET @increment=@increment+1
END
SET @msg = N'Create clustered index on table ' + @tablename + N'.';
EXEC evt.logme @msg;
SET @dsql=N'
CREATE UNIQUE CLUSTERED INDEX cx_FirstNameByBirthDate_'
+ CAST(@min as NVARCHAR(4)) + N'_' + CAST(@max as NVARCHAR(4)) + N'
ON ' + @tablename + N' (FirstNameByBirthDateId, FakeBirthDateStamp)
WITH (SORT_IN_TEMPDB = ON, DATA_COMPRESSION=ROW);'
EXEC sp_executesql @dsql;
GO
/******************************************************/
/* Helper index */
/******************************************************/
EXEC evt.logme N'Create ix_halp ON agg.FirstNameByYearState.';
GO
CREATE NONCLUSTERED INDEX ix_halp
ON agg.FirstNameByYearState (ReportYear)
INCLUDE (FirstNameId, Gender)
WITH (SORT_IN_TEMPDB = ON);
GO
/******************************************************/
/* Turn on Query Store */
/******************************************************/
ALTER DATABASE [BabbyNames] SET QUERY_STORE = ON
GO
ALTER DATABASE [BabbyNames] SET QUERY_STORE (OPERATION_MODE = READ_WRITE)
GO
/******************************************************/
/* Load Data */
/******************************************************/
EXEC evt.logme N'Load dbo.FirstNameByBirthDate_1966_2015.';
GO
EXEC dbo.loaddetail 1966, 2015, N'dbo';
GO
/******************************************************/
/* Create schema pt */
/******************************************************/
EXEC evt.logme N'CREATE SCHEMA pt AUTHORIZATION dbo';
GO
CREATE SCHEMA pt AUTHORIZATION dbo;
GO
EXEC evt.logme N'CREATE PARTITION FUNCTION pf_fnbd.';
GO
CREATE PARTITION FUNCTION pf_fnbd (DATETIME2(0))
AS RANGE RIGHT
FOR VALUES (
'1966-01-01', '1967-01-01', '1968-01-01', '1969-01-01', '1970-01-01',
'1971-01-01', '1972-01-01', '1973-01-01', '1974-01-01', '1975-01-01',
'1976-01-01', '1977-01-01', '1978-01-01', '1979-01-01', '1980-01-01',
'1981-01-01', '1982-01-01', '1983-01-01', '1984-01-01', '1985-01-01',
'1986-01-01', '1987-01-01', '1988-01-01', '1989-01-01', '1990-01-01',
'1991-01-01', '1992-01-01', '1993-01-01', '1994-01-01', '1995-01-01',
'1996-01-01', '1997-01-01', '1998-01-01', '1999-01-01', '2000-01-01',
'2001-01-01', '2002-01-01', '2003-01-01', '2004-01-01', '2005-01-01',
'2006-01-01', '2007-01-01', '2008-01-01', '2009-01-01', '2010-01-01',
'2011-01-01', '2012-01-01', '2013-01-01', '2014-01-01', '2015-01-01',
'2016-01-01', '2017-01-01', '2018-01-01', '2019-01-01', '2020-01-01'
);
GO
EXEC evt.logme N'CREATE PARTITION SCHEME ps_fnbd';
GO
CREATE PARTITION SCHEME ps_fnbd
AS PARTITION pf_fnbd
ALL TO ([fg_FirstNameByBirthDate_pt]);
GO
EXEC evt.logme N'CREATE table pt.FirstNameByBirthDate_1966_2015';
GO
CREATE TABLE pt.FirstNameByBirthDate_1966_2015 (
FakeBirthDateStamp DATETIME2(0) NOT NULL,
FirstNameByBirthDateId BIGINT IDENTITY NOT NULL,
BirthYear AS YEAR(FakeBirthDateStamp) PERSISTED NOT NULL,
StateCode CHAR(2) NOT NULL,
FirstNameId INT NOT NULL,
Gender CHAR(1) NOT NULL
) ON ps_fnbd (FakeBirthDateStamp)
GO
EXEC evt.logme N'Insert data from FirstNameByBirthDate_1966_2015';
GO
SET IDENTITY_INSERT pt.FirstNameByBirthDate_1966_2015 ON;
GO
INSERT pt.FirstNameByBirthDate_1966_2015 WITH (TABLOCK)
(FirstNameByBirthDateId, FakeBirthDateStamp, StateCode, FirstNameId, Gender)
SELECT FirstNameByBirthDateId, FakeBirthDateStamp, StateCode, FirstNameId, Gender
FROM dbo.FirstNameByBirthDate_1966_2015
OPTION (QUERYTRACEON 610)
GO
SET IDENTITY_INSERT pt.FirstNameByBirthDate_1966_2015 OFF;
GO
EXEC evt.logme N'CREATE UNIQUE CLUSTERED INDEX cx_FirstNameByBirthDate_pt';
GO
CREATE UNIQUE CLUSTERED INDEX cx_pt_FirstNameByBirthDate_1966_2015 ON
pt.FirstNameByBirthDate_1966_2015 (FirstNameByBirthDateId, FakeBirthDateStamp)
WITH (SORT_IN_TEMPDB = ON, DATA_COMPRESSION=ROW);
GO
/******************************************************/
/* Cleanup */
/******************************************************/
EXEC evt.logme N'Clean up ix_halp ON agg.FirstNameByYearState.';
GO
DROP INDEX ix_halp ON agg.FirstNameByYearState;
GO
ALTER DATABASE BabbyNames SET DELAYED_DURABILITY = DISABLED;
GO