1. Performance Tuning Scripts
a. Identify Missing Indexes
sqlSELECT
DB_NAME(database_id) AS DatabaseName,
OBJECT_NAME(object_id, database_id) AS TableName,
migs.*,
'CREATE INDEX [IX_' + OBJECT_NAME(object_id, database_id) + '_' + column_name + '] ON [' +
OBJECT_SCHEMA_NAME(object_id, database_id) + '].[' + OBJECT_NAME(object_id, database_id) + '] (' + column_name + ')' AS CreateIndexScript
FROM sys.dm_db_missing_index_details mid
CROSS APPLY (SELECT SCHEMA_NAME(schema_id) + '.' + OBJECT_NAME(object_id) AS TableName,
(SELECT column_name + ', ' AS [text()]
FROM sys.dm_db_missing_index_columns(mid.index_handle)
FOR XML PATH ('')) AS column_name) DerivedData
JOIN sys.dm_db_missing_index_group_stats migs
ON migs.group_handle = mid.index_group_handle
WHERE migs.avg_total_user_cost > 1000
ORDER BY migs.avg_total_user_cost DESC;
b. Index Fragmentation Analysis
sqlSELECT
dbschemas.[name] AS SchemaName,
dbtables.[name] AS TableName,
dbindexes.[name] AS IndexName,
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') indexstats
INNER JOIN sys.objects dbtables ON indexstats.object_id = dbtables.[object_id]
INNER JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id]
INNER JOIN sys.indexes dbindexes ON indexstats.index_id = dbindexes.index_id AND indexstats.object_id = dbindexes.[object_id]
WHERE indexstats.avg_fragmentation_in_percent > 10;
c. Expensive Queries by CPU
sqlSELECT TOP 10
qs.execution_count,
qs.total_logical_reads AS TotalReads,
qs.total_worker_time AS TotalCPU,
qs.total_elapsed_time / 1000 AS TotalElapsedTime_ms,
SUBSTRING(st.text, qs.statement_start_offset / 2,
(CASE
WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), st.text)) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
ORDER BY qs.total_worker_time DESC;
2. Database Object Details
a. List All Tables and Row Counts
sqlSELECT
SCHEMA_NAME(schema_id) AS SchemaName,
t.name AS TableName,
p.rows AS RowCounts
FROM sys.tables t
INNER JOIN sys.partitions p ON t.object_id = p.object_id AND p.index_id < 2
ORDER BY p.rows DESC;
b. Find Object Dependencies
sqlSELECT
referencing.name AS ReferencingObject,
referenced.name AS ReferencedObject,
d.referenced_class_desc
FROM sys.sql_expression_dependencies d
JOIN sys.objects referencing ON d.referencing_id = referencing.object_id
JOIN sys.objects referenced ON d.referenced_id = referenced.object_id;
3. Search for Text in Database Objects
a. Search for Text in Stored Procedures, Views, and Functions
sqlSELECT
OBJECT_NAME(object_id) AS ObjectName,
OBJECT_DEFINITION(object_id) AS ObjectText
FROM sys.sql_modules
WHERE OBJECT_DEFINITION(object_id) LIKE '%YourTextHere%';
b. Search for Text in All Columns of All Tables
sqlDECLARE @SearchText NVARCHAR(100) = 'YourTextHere';
EXEC sp_msforeachtable 'SELECT ''?'' AS TableName, * FROM ? WHERE ''?'' LIKE ''%' + @SearchText + '%''';
4. Other Useful Scripts
a. Check for Blocking Sessions
sqlSELECT
spid AS BlockingSPID,
blocked AS BlockedSPID,
DB_NAME(dbid) AS DatabaseName,
cmd AS Command,
waittype AS WaitType
FROM sys.sysprocesses
WHERE blocked > 0;
b. Identify Long-Running Queries
sqlSELECT
r.session_id,
r.start_time,
DB_NAME(r.database_id) AS DatabaseName,
SUBSTRING(qt.text, r.statement_start_offset / 2,
(CASE
WHEN r.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE r.statement_end_offset
END - r.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) qt
WHERE r.status = 'running'
ORDER BY r.start_time ASC;
Database Object Details
a. List All Indexes with Columns
sqlSELECT
t.name AS TableName,
ind.name AS IndexName,
col.name AS ColumnName,
ic.key_ordinal AS KeyOrder,
ind.type_desc AS IndexType
FROM sys.indexes ind
INNER JOIN sys.index_columns ic ON ind.object_id = ic.object_id AND ind.index_id = ic.index_id
INNER JOIN sys.columns col ON ic.object_id = col.object_id AND ic.column_id = col.column_id
INNER JOIN sys.tables t ON ind.object_id = t.object_id
ORDER BY t.name, ind.name, ic.key_ordinal;
b. Find All User-Defined Tables and Their Sizes
sqlSELECT
t.name AS TableName,
SUM(p.rows) AS TotalRows,
SUM(a.total_pages) * 8 / 1024 AS TotalSize_MB
FROM sys.tables t
INNER JOIN sys.partitions p ON t.object_id = p.object_id
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
WHERE p.index_id IN (0, 1)
GROUP BY t.name
ORDER BY TotalSize_MB DESC;
2. Memory Usage
a. Current Memory Usage by Database
sqlSELECT
DB_NAME(database_id) AS DatabaseName,
COUNT(*) * 8 / 1024 AS MemoryUsage_MB
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY MemoryUsage_MB DESC;
b. Buffer Pool Usage
sqlSELECT
DB_NAME(database_id) AS DatabaseName,
COUNT(*) AS PagesInMemory,
COUNT(*) * 8 / 1024 AS MemoryUsage_MB
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY MemoryUsage_MB DESC;
3. CPU Usage
a. Current CPU Usage by Session
sqlSELECT
r.session_id,
r.cpu_time AS CPUTime_ms,
r.reads AS LogicalReads,
r.writes AS LogicalWrites,
DB_NAME(r.database_id) AS DatabaseName,
SUBSTRING(qt.text, r.statement_start_offset / 2,
(CASE WHEN r.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE r.statement_end_offset END - r.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) qt
ORDER BY r.cpu_time DESC;
4. Duplicate Handling
a. Remove Duplicates While Keeping Original
sqlWITH CTE AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [ColumnToCheck] ORDER BY [PrimaryKeyColumn]) AS RowNum
FROM YourTable
)
DELETE FROM CTE WHERE RowNum > 1;
5. Index Optimization
a. Detect Missing Indexes
sqlSELECT
migs.group_handle,
mid.index_handle,
DB_NAME(mid.database_id) AS DatabaseName,
OBJECT_NAME(mid.object_id, mid.database_id) AS TableName,
mid.equality_columns,
mid.inequality_columns,
mid.included_columns,
migs.avg_total_user_cost,
migs.avg_user_impact
FROM sys.dm_db_missing_index_group_stats migs
INNER JOIN sys.dm_db_missing_index_groups mig
ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details mid
ON mig.index_handle = mid.index_handle
ORDER BY migs.avg_user_impact DESC;
6. Server Usage
a. Server Resource Usage
sqlSELECT
sqlserver_start_time AS StartTime,
cpu_ticks / ms_ticks AS CPUUsage_ms,
physical_memory_kb / 1024 AS TotalMemory_MB
FROM sys.dm_os_sys_info;
7. Network Usage
a. Current Network Statistics
sqlSELECT
net_transport,
auth_scheme,
client_net_address,
local_net_address,
connection_id
FROM sys.dm_exec_connections;
8. sp_who Replacement
a. Enhanced Session Management Query
sqlSELECT
session_id,
login_name,
status,
DB_NAME(database_id) AS DatabaseName,
wait_time,
wait_type,
cpu_time,
memory_usage,
logical_reads,
reads,
writes
FROM sys.dm_exec_sessions
WHERE is_user_process = 1;
9. Concurrent Connection Monitoring
a. Active Connections by Database
sqlSELECT
DB_NAME(dbid) AS DatabaseName,
COUNT(dbid) AS ConnectionCount
FROM sys.sysprocesses
WHERE dbid > 0
GROUP BY dbid
ORDER BY ConnectionCount DESC;
10. Expensive Query Detection
a. Identify Top CPU-Consuming Queries
sqlSELECT TOP 10
qs.execution_count,
qs.total_worker_time / qs.execution_count AS AvgCPUTime_ms,
DB_NAME(qp.dbid) AS DatabaseName,
SUBSTRING(st.text, qs.statement_start_offset / 2,
(CASE WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), st.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
CROSS APPLY sys.dm_exec_plan_attributes(qs.plan_handle) qp
ORDER BY AvgCPUTime_ms DESC;
1. Database Management
a. List All Databases with Recovery Model
sqlSELECT
name AS DatabaseName,
recovery_model_desc AS RecoveryModel
FROM sys.databases
ORDER BY name;
b. Change Recovery Model to Simple
sqlALTER DATABASE [YourDatabaseName]
SET RECOVERY SIMPLE;
c. Database Backup Script
sqlBACKUP DATABASE [YourDatabaseName]
TO DISK = 'C:\\Backup\\YourDatabaseName.bak'
WITH FORMAT, INIT,
NAME = 'Full Backup of YourDatabaseName',
SKIP, NOREWIND, NOUNLOAD, STATS = 10;
2. Database Design
a. List Tables Without Primary Key
sqlSELECT
t.name AS TableName
FROM sys.tables t
LEFT JOIN sys.key_constraints kc ON t.object_id = kc.parent_object_id AND kc.type = 'PK'
WHERE kc.name IS NULL;
b. Identify Foreign Keys Without Indexes
sqlSELECT
fk.name AS ForeignKeyName,
OBJECT_NAME(fk.parent_object_id) AS TableName,
COL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS ColumnName
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
WHERE NOT EXISTS (
SELECT 1
FROM sys.index_columns ic
INNER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE i.is_unique = 1 AND ic.column_id = fkc.parent_column_id
);
3. Query Optimization
a. Identify Queries with High Logical Reads
sqlSELECT TOP 10
total_logical_reads AS LogicalReads,
execution_count AS ExecutionCount,
total_logical_reads / execution_count AS AvgLogicalReads,
SUBSTRING(st.text, qs.statement_start_offset / 2,
(CASE WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), st.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
ORDER BY total_logical_reads DESC;
4. Performance Monitoring
a. Monitor Index Usage
sqlSELECT
OBJECT_NAME(s.object_id) AS TableName,
i.name AS IndexName,
user_seeks,
user_scans,
user_lookups,
user_updates
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON s.object_id = i.object_id AND s.index_id = i.index_id
WHERE s.database_id = DB_ID('YourDatabaseName')
ORDER BY user_seeks DESC;
b. Check Wait Statistics
sqlSELECT
wait_type,
wait_time_ms / 1000 AS WaitTimeSeconds,
signal_wait_time_ms / 1000 AS SignalWaitTimeSeconds,
waiting_tasks_count AS WaitingTasks
FROM sys.dm_os_wait_stats
ORDER BY wait_time_ms DESC;
5. Troubleshooting
a. Find Blocked and Blocking Sessions
sqlSELECT
spid AS SessionID,
blocked AS BlockingSessionID,
DB_NAME(dbid) AS DatabaseName,
waittype AS WaitType,
cmd AS Command
FROM sys.sysprocesses
WHERE blocked > 0;
b. Detect Deadlocks
sqlSELECT
XEventData.value('(event/action[@name=\"session_id\"]/value)[1]', 'INT') AS SessionID,
XEventData.value('(event/data[@name=\"database_name\"]/value)[1]', 'NVARCHAR(MAX)') AS DatabaseName,
XEventData.value('(event/data[@name=\"object_name\"]/value)[1]', 'NVARCHAR(MAX)') AS ObjectName
FROM (SELECT CAST(target_data AS XML) AS TargetData
FROM sys.dm_xe_session_targets st
JOIN sys.dm_xe_sessions s ON s.address = st.event_session_address
WHERE st.target_name = 'ring_buffer' AND s.name = 'system_health') AS XEvent
CROSS APPLY TargetData.nodes('//event[@name=\"deadlock\"]/data') AS XEventData(event);
6. Session Management
a. Kill a Session
sqlKILL [SessionID];
b. List Active Sessions
sqlSELECT
session_id,
login_name,
status,
DB_NAME(database_id) AS DatabaseName,
cpu_time,
memory_usage,
logical_reads,
reads,
writes
FROM sys.dm_exec_sessions
WHERE is_user_process = 1
ORDER BY cpu_time DESC;
7. Advanced Analysis
a. Identify Most Used Tables
sqlSELECT
OBJECT_NAME(p.object_id) AS TableName,
i.name AS IndexName,
dm_logical_reads + dm_physical_reads AS TotalReads
FROM sys.dm_db_index_usage_stats us
INNER JOIN sys.partitions p ON us.object_id = p.object_id
INNER JOIN sys.indexes i ON us.index_id = i.index_id
ORDER BY TotalReads DESC;
b. Analyze IO Bottlenecks
sqlSELECT
database_id,
file_id,
num_of_reads,
num_of_writes,
io_stall_read_ms,
io_stall_write_ms
FROM sys.dm_io_virtual_file_stats(NULL, NULL);
8. User Management
a. List All Users and Roles
sqlSELECT
u.name AS UserName,
r.name AS RoleName
FROM sys.database_principals u
LEFT JOIN sys.database_role_members rm ON u.principal_id = rm.member_principal_id
LEFT JOIN sys.database_principals r ON rm.role_principal_id = r.principal_id
WHERE u.type IN ('S', 'U') AND u.name NOT LIKE '##%';
b. Grant Permissions to a User
sqlGRANT SELECT, INSERT, UPDATE, DELETE ON [YourTable] TO [YourUser];
9. Backup and Restore Management
a. View Backup History
sqlSELECT
database_name,
backup_start_date,
backup_finish_date,
backup_size / 1024 / 1024 AS BackupSize_MB,
physical_device_name
FROM msdb.dbo.backupset bs
INNER JOIN msdb.dbo.backupmediafamily bmf ON bs.media_set_id = bmf.media_set_id
ORDER BY backup_start_date DESC;
b. Restore Database
sqlRESTORE DATABASE [YourDatabaseName]
FROM DISK = 'C:\\Backup\\YourDatabaseName.bak'
WITH MOVE 'LogicalDataFileName' TO 'C:\\Data\\YourDatabaseName.mdf',
MOVE 'LogicalLogFileName' TO 'C:\\Data\\YourDatabaseName.ldf';
10. Extended Database Management
a. Check Disk Space Used by Database Files
sqlSELECT
DB_NAME(database_id) AS DatabaseName,
type_desc AS FileType,
name AS LogicalFileName,
physical_name AS PhysicalFileName,
size * 8 / 1024 AS Size_MB,
size * 8 / 1024 / 1024 AS Size_GB
FROM sys.master_files
ORDER BY DatabaseName;
b. Shrink Database Log File
sqlDBCC SHRINKFILE ('LogicalLogFileName', 10); -- Shrink to 10MB
c. Rebuild All Indexes in a Database
sqlDECLARE @TableName NVARCHAR(MAX);
DECLARE TableCursor CURSOR FOR
SELECT '[' + SCHEMA_NAME(schema_id) + '].[' + name + ']' AS TableName
FROM sys.tables;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('ALTER INDEX ALL ON ' + @TableName + ' REBUILD');
FETCH NEXT FROM TableCursor INTO @TableName;
END;
CLOSE TableCursor;
DEALLOCATE TableCursor;
11. Security and User Management
a. Check User Permissions
sqlSELECT
grantee.name AS UserName,
permission_name AS Permission,
class_desc AS ObjectType,
major_id AS ObjectID,
OBJECT_NAME(major_id) AS ObjectName
FROM sys.database_permissions p
JOIN sys.database_principals grantee ON p.grantee_principal_id = grantee.principal_id;
b. Disable User Account
sqlALTER LOGIN [UserName] DISABLE;
c. Identify Orphaned Users
sqlSELECT
dp.name AS UserName
FROM sys.database_principals dp
LEFT JOIN sys.server_principals sp ON dp.sid = sp.sid
WHERE dp.type IN ('S', 'U') AND sp.sid IS NULL;
12. Query Optimization
a. Identify Queries with High Execution Times
sqlSELECT TOP 10
total_elapsed_time / 1000 AS TotalElapsedTime_ms,
execution_count,
SUBSTRING(qt.text, qs.statement_start_offset / 2,
(CASE WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
ORDER BY TotalElapsedTime_ms DESC;
b. Detect Implicit Conversions in Queries
sqlSELECT
OBJECT_NAME(st.objectid) AS ObjectName,
st.text AS QueryText,
cp.usecounts AS PlanReuseCount
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
WHERE st.text LIKE '%CONVERT%';
13. Troubleshooting
a. Identify Unused Indexes
sqlSELECT
OBJECT_NAME(i.object_id) AS TableName,
i.name AS IndexName,
s.user_seeks + s.user_scans + s.user_lookups AS TotalAccesses,
s.user_updates AS TotalUpdates
FROM sys.indexes i
LEFT JOIN sys.dm_db_index_usage_stats s ON i.object_id = s.object_id AND i.index_id = s.index_id
WHERE s.user_seeks + s.user_scans + s.user_lookups = 0
AND i.is_primary_key = 0
AND i.is_unique_constraint = 0;
b. Identify High Disk IO Queries
sqlSELECT TOP 10
total_physical_reads AS TotalReads,
execution_count,
SUBSTRING(qt.text, qs.statement_start_offset / 2,
(CASE WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) AS QueryText
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
ORDER BY TotalReads DESC;
14. Session and Connection Management
a. List Open Transactions
sqlDBCC OPENTRAN;
b. Detect Active Locks
sqlSELECT
resource_type,
resource_description,
request_mode,
request_status,
request_session_id
FROM sys.dm_tran_locks;
c. Disconnect All Sessions from a Database
sqlALTER DATABASE [YourDatabaseName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
15. Backup and Restore
a. Differential Backup
sqlBACKUP DATABASE [YourDatabaseName]
TO DISK = 'C:\\Backup\\YourDatabaseName_Diff.bak'
WITH DIFFERENTIAL, INIT, STATS = 10;
b. Restore with Standby
sqlRESTORE DATABASE [YourDatabaseName]
FROM DISK = 'C:\\Backup\\YourDatabaseName.bak'
WITH STANDBY = 'C:\\Backup\\YourDatabaseName_Standby.ldf';
16. Advanced Analysis
a. Table Statistics
sqlDBCC SHOW_STATISTICS ('YourTable', 'YourIndexName');
b. Identify Tables Without Statistics
sqlSELECT
t.name AS TableName
FROM sys.tables t
WHERE NOT EXISTS (
SELECT 1
FROM sys.stats s
WHERE s.object_id = t.object_id);
c. Monitor TempDB Usage
sqlSELECT
session_id,
user_objects_alloc_page_count AS UserObjectsPages,
internal_objects_alloc_page_count AS InternalObjectsPages
FROM sys.dm_db_task_space_usage;
17. Maintenance
a. Update Statistics
sqlEXEC sp_updatestats;
b. Reorganize Indexes
sqlDECLARE @TableName NVARCHAR(MAX);
DECLARE TableCursor CURSOR FOR
SELECT '[' + SCHEMA_NAME(schema_id) + '].[' + name + ']' AS TableName
FROM sys.tables;
OPEN TableCursor;
FETCH NEXT FROM TableCursor INTO @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('ALTER INDEX ALL ON ' + @TableName + ' REORGANIZE');
FETCH NEXT FROM TableCursor INTO @TableName;
END;
CLOSE TableCursor;
DEALLOCATE TableCursor;
0 comments:
Post a Comment