Skip to content

Commit c413754

Browse files
committed
Performance standardised headings
1 parent 79410ea commit c413754

21 files changed

+548
-689
lines changed

Auditing/Create audit for database.sql

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
33
-- This script creates server and database audits for the nominated database
44
-- Values to be modified before execution:
5-
DECLARE @DBName VARCHAR(100) = '<DatabaseName>';
6-
DECLARE @AuditPath VARCHAR(100) = '<PathToAuditsFolder>' + '\' + @DBName;
5+
DECLARE @DBName VARCHAR(100) = ''<DatabaseName>'';
6+
DECLARE @AuditPath VARCHAR(100) = ''<PathToAuditsFolder>'' + ''\'' + @DBName;
77

88
DECLARE @createDirSql NVARCHAR(100);
99

10-
SET @createDirSql = N'EXEC master.sys.xp_create_subdir ''' + @AuditPath + N'''';
10+
SET @createDirSql = N''EXEC master.sys.xp_create_subdir '' + @AuditPath + N'';
1111

1212
EXEC sys.sp_executesql @stmt = @createDirSql;
1313

1414
DECLARE @AuditSql NVARCHAR(1000);
1515

1616
SET @AuditSql
17-
= N'USE master;' + N'CREATE SERVER AUDIT [' + @DBName + N'] ' + N'TO FILE ( FILEPATH = ''' + @AuditPath
18-
+ N''', MAXSIZE = 1GB, MAX_ROLLOVER_FILES = 15, RESERVE_DISK_SPACE = OFF ) WITH ( QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE );'
19-
+ N'ALTER SERVER AUDIT [' + @DBName + N'] WITH (STATE = ON);' + N'USE [' + @DBName + N'];'
20-
+ N'CREATE DATABASE AUDIT SPECIFICATION [' + @DBName + N']' + N'FOR SERVER AUDIT [' + @DBName + N']'
21-
+ N'ADD (SCHEMA_OBJECT_ACCESS_GROUP) WITH (STATE = ON);';
17+
= N''USE master;'' + N''CREATE SERVER AUDIT ['' + @DBName + N''] '' + N''TO FILE ( FILEPATH = '' + @AuditPath
18+
+ N'', MAXSIZE = 1GB, MAX_ROLLOVER_FILES = 15, RESERVE_DISK_SPACE = OFF ) WITH ( QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE );''
19+
+ N''ALTER SERVER AUDIT ['' + @DBName + N''] WITH (STATE = ON);'' + N''USE ['' + @DBName + N''];''
20+
+ N''CREATE DATABASE AUDIT SPECIFICATION ['' + @DBName + N'']'' + N''FOR SERVER AUDIT ['' + @DBName + N'']''
21+
+ N''ADD (SCHEMA_OBJECT_ACCESS_GROUP) WITH (STATE = ON);'';
2222

2323
EXEC sys.sp_executesql @stmt = @AuditSql;
2424
GO
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- List all extended events sessions and whether they are running
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script lists the name of the Extended Events session and either 'Running' or 'Stopped'.
4+
5+
SELECT ses.name,
6+
CASE
7+
WHEN dxs.name IS NULL THEN
8+
'Stopped'
9+
ELSE
10+
'Running'
11+
END AS State
12+
FROM sys.server_event_sessions AS ses
13+
LEFT OUTER JOIN sys.dm_xe_sessions AS dxs
14+
ON ses.name = dxs.name;
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,44 @@
1+
-- Analyzing 'death by a thousand cuts' workloads
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script looks for top queries based on execution count, grouped by query_hash, to show both frequently executed stored procedures
4+
-- and ad-hoc queries.
15
-- From https://sqlperformance.com/2019/10/t-sql-queries/death-by-a-thousand-cuts
2-
;WITH qh AS
3-
(
4-
SELECT TOP (25) query_hash, COUNT(*) AS COUNT
6+
7+
;WITH qh
8+
AS (SELECT TOP (25)
9+
query_hash,
10+
COUNT(*) AS COUNT
511
FROM sys.dm_exec_query_stats
612
GROUP BY query_hash
7-
ORDER BY COUNT(*) DESC
8-
),
9-
qs AS
10-
(
11-
SELECT obj = COALESCE(ps.object_id, fs.object_id, ts.object_id),
12-
db = COALESCE(ps.database_id, fs.database_id, ts.database_id),
13-
qs.query_hash, qs.query_plan_hash, qs.execution_count,
14-
qs.sql_handle, qs.plan_handle
13+
ORDER BY COUNT(*) DESC),
14+
qs
15+
AS (SELECT obj = COALESCE(ps.object_id, fs.object_id, ts.object_id),
16+
db = COALESCE(ps.database_id, fs.database_id, ts.database_id),
17+
qs.query_hash,
18+
qs.query_plan_hash,
19+
qs.execution_count,
20+
qs.sql_handle,
21+
qs.plan_handle
1522
FROM sys.dm_exec_query_stats AS qs
16-
INNER JOIN qh ON qs.query_hash = qh.query_hash
17-
LEFT OUTER JOIN sys.dm_exec_procedure_stats AS [ps]
18-
ON [qs].[sql_handle] = [ps].[sql_handle]
19-
LEFT OUTER JOIN sys.dm_exec_function_stats AS [fs]
20-
ON [qs].[sql_handle] = [fs].[sql_handle]
21-
LEFT OUTER JOIN sys.dm_exec_trigger_stats AS [ts]
22-
ON [qs].[sql_handle] = [ts].[sql_handle]
23-
)
23+
INNER JOIN qh
24+
ON qs.query_hash = qh.query_hash
25+
LEFT OUTER JOIN sys.dm_exec_procedure_stats AS [ps]
26+
ON [qs].[sql_handle] = [ps].[sql_handle]
27+
LEFT OUTER JOIN sys.dm_exec_function_stats AS [fs]
28+
ON [qs].[sql_handle] = [fs].[sql_handle]
29+
LEFT OUTER JOIN sys.dm_exec_trigger_stats AS [ts]
30+
ON [qs].[sql_handle] = [ts].[sql_handle])
2431
SELECT TOP (50)
25-
object_name = OBJECT_NAME(qs.obj, qs.db),
26-
query_hash,
27-
query_plan_hash,
28-
SUM([qs].[execution_count]) AS [ExecutionCount],
29-
MAX([st].[text]) AS [QueryText]
30-
FROM qs
31-
CROSS APPLY sys.dm_exec_sql_text ([qs].[sql_handle]) AS [st]
32-
CROSS APPLY sys.dm_exec_query_plan ([qs].[plan_handle]) AS [qp]
33-
GROUP BY qs.obj, qs.db, qs.query_hash, qs.query_plan_hash
34-
ORDER BY ExecutionCount DESC;
32+
object_name = OBJECT_NAME(qs.obj, qs.db),
33+
qs.query_hash,
34+
qs.query_plan_hash,
35+
SUM(qs.execution_count) AS [ExecutionCount],
36+
MAX(st.text) AS [QueryText]
37+
FROM qs
38+
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS [st]
39+
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS [qp]
40+
GROUP BY qs.obj,
41+
qs.db,
42+
qs.query_hash,
43+
qs.query_plan_hash
44+
ORDER BY ExecutionCount DESC;

Performance/Breakdown of buffer cache usage by database.sql

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
----------------------------------------------
21
-- Breakdown of buffer cache usage by database
3-
--
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script analyses which databases have been using how much of the buffer cache memory
44
-- From https://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/
5-
----------------------------------------------
65

76
DECLARE @total_buffer INT;
87

@@ -16,8 +15,7 @@ AS (SELECT database_id,
1615
db_buffer_pages = COUNT_BIG(*)
1716
FROM sys.dm_os_buffer_descriptors
1817
--WHERE database_id BETWEEN 5 AND 32766
19-
GROUP BY database_id
20-
)
18+
GROUP BY database_id)
2119
SELECT [db_name] = CASE [database_id]
2220
WHEN 32767 THEN
2321
'Resource DB'

Performance/Breakdown of buffer cache usage for a specific database.sql

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
----------------------------------------------------------
21
-- Breakdown of buffer cache usage for a specific database
3-
--
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script analyses which clustered and non-clustered indexes have been using how much of the buffer cache memory for this database.
44
-- From https://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/
5-
----------------------------------------------------------
65

7-
USE [eviQ.CMS];
6+
USE [<DatabaseName>];
87
GO
98

109
;WITH src
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
1-
/* Declare Parameters */
2-
DECLARE @newBaseline BIT = 1 -- change to 0 when you don't want to replace the baseline, i.e. after initial run
3-
, @delay CHAR(8) = '00:00:30'; -- change as needed
4-
5-
IF @newBaseline = 1
1+
-- Calculate rows inserted per second for all tables
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script gets a count of rows in all tables in this database, waits for 30 secs, then compares and calculates rows inserted per second.
4+
-- Values to be modified before execution:
5+
DECLARE @newBaseline BIT = 1, -- change to 0 when you don't want to replace the baseline, i.e. after initial run
6+
@delay CHAR(8) = '00:00:30'; -- change as needed
7+
8+
IF @newBaseline = 1
69
BEGIN
710
IF OBJECT_ID('tempdb..#baseline') IS NOT NULL
811
DROP TABLE #baseline;
9-
12+
1013
CREATE TABLE #baseline
1114
(
12-
database_name SYSNAME NULL
13-
, table_name SYSNAME NULL
14-
, table_rows BIGINT NULL
15-
, captureTime DATETIME NULL
15+
database_name sysname NULL,
16+
table_name sysname NULL,
17+
table_rows BIGINT NULL,
18+
captureTime DATETIME NULL
1619
);
17-
END
18-
20+
END;
21+
1922
IF OBJECT_ID('tempdb..#current') IS NOT NULL
2023
DROP TABLE #current;
21-
24+
2225
CREATE TABLE #current
2326
(
24-
database_name SYSNAME NULL
25-
, table_name SYSNAME NULL
26-
, table_rows BIGINT NULL
27-
, captureTime DATETIME NULL
27+
database_name sysname NULL,
28+
table_name sysname NULL,
29+
table_rows BIGINT NULL,
30+
captureTime DATETIME NULL
2831
);
29-
30-
IF @newBaseline = 1
32+
33+
IF @newBaseline = 1
3134
BEGIN
3235
EXECUTE dbo.sp_ineachdb @command = '
3336
INSERT INTO #baseline
@@ -42,11 +45,11 @@ BEGIN
4245
JOIN sys.objects As o
4346
ON i.[object_id] = o.[object_id]
4447
WHERE i.[type] = 1
45-
GROUP BY o.name;'
46-
48+
GROUP BY o.name;';
49+
4750
WAITFOR DELAY @delay;
48-
END
49-
51+
END;
52+
5053
EXECUTE dbo.sp_ineachdb @command = '
5154
INSERT INTO #current
5255
SELECT DB_NAME()
@@ -60,17 +63,17 @@ JOIN sys.partitions As p
6063
JOIN sys.objects As o
6164
ON i.[object_id] = o.[object_id]
6265
WHERE i.[type] = 1
63-
GROUP BY o.name;'
64-
65-
SELECT c.database_name,
66-
c.table_name,
67-
c.table_rows,
68-
c.captureTime
69-
, c.table_rows - b.table_rows AS new_rows
70-
, DATEDIFF(second, b.captureTime, c.captureTime) AS time_diff
71-
, (c.table_rows - b.table_rows) / DATEDIFF(second, b.captureTime, c.captureTime) AS rows_per_sec
66+
GROUP BY o.name;';
67+
68+
SELECT c.database_name,
69+
c.table_name,
70+
c.table_rows,
71+
c.captureTime,
72+
c.table_rows - b.table_rows AS new_rows,
73+
DATEDIFF(SECOND, b.captureTime, c.captureTime) AS time_diff,
74+
(c.table_rows - b.table_rows) / DATEDIFF(SECOND, b.captureTime, c.captureTime) AS rows_per_sec
7275
FROM #baseline AS b
73-
JOIN #current AS c
74-
ON b.table_name = c.table_name
75-
AND b.database_name = c.database_name
76+
JOIN #current AS c
77+
ON b.table_name = c.table_name
78+
AND b.database_name = c.database_name
7679
ORDER BY new_rows DESC;
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,41 @@
1-
/*----------------------------------------------------------------------
2-
Purpose: Identify columns having different datatypes, for the same column name.
3-
Sorted by the prevalence of the mismatched column.
4-
------------------------------------------------------------------------
5-
Revision History:
6-
06/01/2008 [email protected] Initial version.
7-
-----------------------------------------------------------------------*/
8-
-- Do not lock anything, and do not get held up by any locks.
9-
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
10-
-- Calculate prevalence of column name
11-
SELECT
12-
COLUMN_NAME
13-
,[%] = CONVERT(DECIMAL(12,2),COUNT(COLUMN_NAME)* 100.0 / COUNT(*)OVER())
14-
INTO #Prevalence
15-
FROM INFORMATION_SCHEMA.COLUMNS
16-
GROUP BY COLUMN_NAME
17-
-- Do the columns differ on datatype across the schemas and tables?
18-
SELECT DISTINCT
19-
C1.COLUMN_NAME
20-
, C1.TABLE_SCHEMA
21-
, C1.TABLE_NAME
22-
, C1.DATA_TYPE
23-
, C1.CHARACTER_MAXIMUM_LENGTH
24-
, C1.NUMERIC_PRECISION
25-
, C1.NUMERIC_SCALE
26-
, [%]
27-
FROM INFORMATION_SCHEMA.COLUMNS C1
28-
INNER JOIN INFORMATION_SCHEMA.COLUMNS C2 ON C1.COLUMN_NAME = C2.COLUMN_NAME
29-
INNER JOIN #Prevalence p ON p.COLUMN_NAME = C1.COLUMN_NAME
30-
WHERE ((C1.DATA_TYPE != C2.DATA_TYPE)
31-
OR (C1.CHARACTER_MAXIMUM_LENGTH != C2.CHARACTER_MAXIMUM_LENGTH)
32-
OR (C1.NUMERIC_PRECISION != C2.NUMERIC_PRECISION)
33-
OR (C1.NUMERIC_SCALE != C2.NUMERIC_SCALE))
34-
ORDER BY [%] DESC, C1.COLUMN_NAME, C1.TABLE_SCHEMA, C1.TABLE_NAME
35-
-- Tidy up.
36-
DROP TABLE #Prevalence
1+
-- Find mismatching column types in database schema
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script identifies columns having different datatypes, for the same column name, sorted by the prevalence of the mismatched column
4+
5+
-- Do not lock anything, and do not get held up by any locks.
6+
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
7+
8+
-- Calculate prevalence of column name
9+
SELECT COLUMN_NAME,
10+
[%] = CONVERT(DECIMAL(12, 2), COUNT(COLUMN_NAME) * 100.0 / COUNT(*) OVER ())
11+
INTO #Prevalence
12+
FROM INFORMATION_SCHEMA.COLUMNS
13+
GROUP BY COLUMN_NAME;
14+
15+
-- Do the columns differ on datatype across the schemas and tables?
16+
SELECT DISTINCT
17+
C1.COLUMN_NAME,
18+
C1.TABLE_SCHEMA,
19+
C1.TABLE_NAME,
20+
C1.DATA_TYPE,
21+
C1.CHARACTER_MAXIMUM_LENGTH,
22+
C1.NUMERIC_PRECISION,
23+
C1.NUMERIC_SCALE,
24+
p.[%]
25+
FROM INFORMATION_SCHEMA.COLUMNS C1
26+
INNER JOIN INFORMATION_SCHEMA.COLUMNS C2
27+
ON C1.COLUMN_NAME = C2.COLUMN_NAME
28+
INNER JOIN #Prevalence p
29+
ON p.COLUMN_NAME = C1.COLUMN_NAME
30+
WHERE (
31+
(C1.DATA_TYPE <> C2.DATA_TYPE)
32+
OR (C1.CHARACTER_MAXIMUM_LENGTH <> C2.CHARACTER_MAXIMUM_LENGTH)
33+
OR (C1.NUMERIC_PRECISION <> C2.NUMERIC_PRECISION)
34+
OR (C1.NUMERIC_SCALE <> C2.NUMERIC_SCALE)
35+
)
36+
ORDER BY p.[%] DESC,
37+
C1.COLUMN_NAME,
38+
C1.TABLE_SCHEMA,
39+
C1.TABLE_NAME;
40+
41+
DROP TABLE #Prevalence;
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1+
-- Find non-zero fill factors for identity columns (set back to 100)
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script lists identity columns that have a FILLFACTOR value that is neither 0 nor 100, and provides the ALTER INDEX statement to fix it.
4+
15
EXEC dbo.sp_ineachdb @command = '
2-
SELECT OBJECT_NAME(i.object_id) AS TableName, i.name AS index_name, COL_NAME(ic.object_id, ic.column_id) AS column_name, ''ALTER INDEX ['' + i.NAME + ''] ON ['' + OBJECT_NAME(i.object_id) + ''] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, FILLFACTOR = 100)'' AS RebuildSQL
3-
FROM sys.indexes AS i
4-
INNER JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
5-
AND i.index_id = ic.index_id
6-
INNER JOIN sys.columns AS c ON c.object_id = ic.object_id
7-
AND c.column_id = ic.column_id
8-
WHERE i.fill_factor != 0
9-
AND c.is_identity = 1;
6+
SELECT OBJECT_NAME(i.object_id) AS TableName,
7+
i.name AS index_name,
8+
COL_NAME(ic.object_id, ic.column_id) AS column_name,
9+
i.fill_factor AS fill_factor,
10+
''ALTER INDEX ['' + i.name + ''] ON ['' + OBJECT_NAME(i.object_id)
11+
+ ''] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, FILLFACTOR = 100)'' AS RebuildSQL
12+
FROM sys.indexes AS i
13+
INNER JOIN sys.index_columns AS ic
14+
ON i.object_id = ic.object_id
15+
AND i.index_id = ic.index_id
16+
INNER JOIN sys.columns AS c
17+
ON c.object_id = ic.object_id
18+
AND c.column_id = ic.column_id
19+
WHERE i.fill_factor <> 0
20+
AND i.fill_factor <> 100
21+
AND c.is_identity = 1;
1022
';
+13-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
1-
EXEC dbo.sp_ineachdb @command = 'SELECT ''?'' AS DatabaseName, OBJECT_NAME(object_id) AS TableName, name AS IndexName, fill_factor FROM sys.indexes WHERE fill_factor != 0';
1+
-- Find non-zero fill factors
2+
-- Part of the SQL Server DBA Toolbox at https://github.com/DavidSchanzer/Sql-Server-DBA-Toolbox
3+
-- This script finds all indexes that have a fill factor that is neither 0 nor 100
4+
5+
EXEC dbo.sp_ineachdb @command = '
6+
SELECT ''?'' AS DatabaseName,
7+
OBJECT_NAME(object_id) AS TableName,
8+
name AS IndexName,
9+
fill_factor
10+
FROM sys.indexes
11+
WHERE fill_factor <> 0 AND fill_factor <> 100;
12+
',
13+
@user_only = 1;

0 commit comments

Comments
 (0)