Query 1
Individual File Sizes and space available for current database(File Sizes and Space)
SELECT f.NAME AS [file name], f.physical_nameas [physical name], Cast(( f.size / 128.0 ) AS DECIMAL(15, 2)) AS [total size in mb], Cast(f.size / 128.0 - Cast(Fileproperty(f.NAME, 'spaceused') AS INT) / 128.0 AS DECIMAL(15, 2)) AS [available space in mb], f.[file_id], fg.NAME AS [filegroup name], f.is_percent_growth, f.growth, fg.is_default, fg.is_read_only, fg.is_autogrow_all_files FROM sys.database_files AS f WITH (nolock) LEFT OUTER JOIN sys.filegroups AS fg WITH (nolock) ON f.data_space_id = fg.data_space_id ORDER BY f.[file_id] OPTION (recompile); |
Look at how large and how full the
files are and where they are located.Make sure the transaction log is not
full!!Is_autogrow_all_files is new for SQL Server 2016. Equivalent to TF 1117
for user databases.
Query 2
Log space usage for current database(Log SpaceUsage)
SELECT Db_name(lsu.database_id) AS [database name], db.recovery_model_desc AS [recovery model], Cast(total_log_size_in_bytes / 1048576.0 AS DECIMAL(10, 2)) AS [total log space (mb)], Cast(used_log_space_in_bytes / 1048576.0 AS DECIMAL(10, 2)) AS [used log space (mb)], Cast(used_log_space_in_percent AS DECIMAL(10, 2)) AS [used log space %], Cast(log_space_in_bytes_since_last_backup / 1048576.0 AS DECIMAL(10, 2)) AS [used log space since last backup (mb)], db.log_reuse_wait_desc FROM sys.dm_db_log_space_usage AS lsu WITH (nolock) INNER JOIN sys.databases AS db WITH (nolock) ON lsu.database_id = db.database_id OPTION (recompile); |
Look at log file size and usage,
along with thelog reuse wait description for the current database.
Query 3
Get database scoped configuration values for current database(Database-scoped Configurations)
SELECT configuration_id, NAME, [value] AS [value_for_primary], value_for_secondary FROM sys.database_scoped_configurations WITH (nolock) OPTION (recompile); This lets you see the value of these new properties for the current database.Clear plan cache for current database. ALTER DATABASE scoped configuration clear procedure_cache; ALTER DATABASE scoped configuration (transact-sql) |
Query 4
I/O Statistics by file for the current database(IO Stats By File)
SELECT Db_name(Db_id()) AS [database name], df.NAME AS [logical name], vfs.[file_id], df.type_desc, df.physical_name AS [physical name], Cast(vfs.size_on_disk_bytes / 1048576.0 AS DECIMAL(10, 2)) AS [size on disk(mb)], vfs.num_of_reads, vfs.num_of_writes, vfs.io_stall_read_ms, vfs.io_stall_write_ms, Cast(100. * vfs.io_stall_read_ms / ( vfs.io_stall_read_ms + vfs.io_stall_write_ms ) AS DECIMAL (10, 1) ) AS [io stall reads pct], Cast(100. * vfs.io_stall_write_ms / ( vfs.io_stall_write_ms + vfs.io_stall_read_ms ) AS DECIMAL (10, 1) ) AS [io stall writes pct], ( vfs.num_of_reads + vfs.num_of_writes ) AS [writes + reads], Cast(vfs.num_of_bytes_read / 1048576.0 AS DECIMAL(10, 2)) AS [mb read] , Cast(vfs.num_of_bytes_written / 1048576.0 AS DECIMAL(10, 2)) AS [mb written], Cast(100. * vfs.num_of_reads / ( vfs.num_of_reads + vfs.num_of_writes ) AS DECIMAL(10, 1)) AS [# reads pct], Cast(100. * vfs.num_of_writes / ( vfs.num_of_reads + vfs.num_of_writes ) AS DECIMAL( 10, 1)) AS [# write pct], Cast(100. * vfs.num_of_bytes_read / ( vfs.num_of_bytes_read + vfs.num_of_bytes_written ) AS DECIMAL(10, 1)) AS [read bytes pct], Cast(100. * vfs.num_of_bytes_written / ( vfs.num_of_bytes_read + vfs.num_of_bytes_written ) AS DECIMAL (10, 1)) AS [written bytes pct] FROM sys.Dm_io_virtual_file_stats(Db_id(), NULL) AS vfsinner JOIN sys.database_files AS df WITH (nolock) ON vfs.[file_id] = df.[file_id] OPTION (recompile); |
This helps you characterize your
workload better from an I/O perspective for this database.It helps you
determine whether you has an OLTP or DW/DSS type of workload.
Query 5
Get most frequently executed queries for this database(Query Execution Counts)
SELECT TOP(50) LEFT(t.[text], 50) AS [shortquery text], qs.execution_count AS [execution count], qs.total_logical_reads AS [total logical reads], qs.total_logical_reads/qs.execution_count AS [avg logical reads], qs.total_worker_time AS [total worker time], qs.total_worker_time/qs.execution_count AS [avg worker time], qs.total_elapsed_time AS [total elapsed time], qs.total_elapsed_time/qs.execution_count AS [avg elapsed time], qs.creation_time AS [creation time]--,t.[text] as [complete query text], qp.query_plan AS [query plan] -- uncomment out these columns if not copying results to excel FROM sys.dm_exec_query_stats AS qs WITH (nolock) CROSS apply sys.dm_exec_sql_text(plan_handle) AS t CROSS apply sys.dm_exec_query_plan(plan_handle) AS qp WHERE t.dbid = db_id() ORDER BY qs.execution_count DESC OPTION (recompile); |
Query 6
Top Cached SPs By Execution Count(SP Execution Counts)
SELECT TOP(100) p.NAME AS [sp name], qs.execution_count, Isnull(qs.execution_count / Datediff(minute, qs.cached_time, Getdate()), 0) AS [calls/minute], qs.total_worker_time / qs.execution_count AS [avgworkertime], qs.total_worker_time AS [totalworkertime], qs.total_elapsed_time, qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time], qs.cached_time FROM sys.procedures AS p WITH (nolock) INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (nolock) ON p.[object_id] = qs.[object_id] WHERE qs.database_id = Db_id() ORDER BY qs.execution_count DESC OPTION (recompile); |
Tells you which cached stored
procedures are called the most often.This helps you characterize and baseline
your workload.
Query 7
Top Cached SPs By Avg Elapsed Time(SP Avg Elapsed Time)
SELECT TOP(25) p.NAME AS [sp name], qs.min_elapsed_time, qs.total_elapsed_time/qs.execution_count AS[avg_elapsed_time], qs.max_elapsed_time, qs.last_elapsed_time, qs.total_elapsed_time, qs.execution_count, Isnull(qs.execution_count/Datediff(minute, qs.cached_time, Getdate()), 0) AS [calls/minute], qs.total_worker_time/qs.execution_count AS [avgworkertime], qs.total_worker_time AS [totalworkertime], qs.cached_timefrom sys.procedures as p WITH (nolock) INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (nolock) ON p.[object_id] = qs.[object_id] WHERE qs.database_id = db_id() ORDER BY avg_elapsed_time DESC OPTION (recompile); |
This helps you find high average
elapsed time cached stored procedures that.May be easy to optimize with
standard query tuning techniques.
Query 8
Top Cached SPs By Total Worker time. Worker time relates to CPU cost(SP Worker Time)
SELECT TOP(25) p.NAME AS [sp name], qs.total_worker_time AS [totalworkertime], qs.total_worker_time / qs.execution_count AS [avgworkertime], qs.execution_count, Isnull(qs.execution_count / Datediff(minute, qs.cached_time, Getdate()), 0) AS [calls/minute], qs.total_elapsed_time, qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time], qs.cached_time FROM sys.procedures AS p WITH (nolock) INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (nolock) ON p.[object_id] = qs.[object_id] WHERE qs.database_id = Db_id() ORDER BY qs.total_worker_time DESC OPTION (recompile); |
This helps you find the most expensive cached stored procedures from a CPU
perspective.You should look at this if you see signs of CPU pressure.
Query 9
SELECT TOP(25) p.NAME AS [SP Name], qs.total_logical_reads AS [TotalLogicalReads], qs.total_logical_reads / qs.execution_count AS [AvgLogicalReads], qs.execution_count, Isnull(qs.execution_count / Datediff(minute, qs.cached_time, Getdate()), 0) AS [Calls/Minute], qs.total_elapsed_time, qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time], qs.cached_time FROM sys.procedures AS p WITH (nolock) INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (nolock) ON p.[object_id] = qs.[object_id] WHERE qs.database_id = Db_id() ORDER BY qs.total_logical_reads DESC OPTION (recompile); |
This helps you find the most
expensive cached stored procedures from a memory perspective.You should look at
this if you see signs of memory pressure.
Query 10
Top Cached SPs By Total Physical Reads. Physical reads relate to disk read I/O pressure(SP Physical Reads)
SELECT TOP(25) p.NAME AS [SP Name], qs.total_physical_reads AS [TotalPhysicalReads], qs.total_physical_reads / qs.execution_count AS [AvgPhysicalReads], qs.execution_count, qs.total_logical_reads, qs.total_elapsed_time, qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time], qs.cached_time FROM sys.procedures AS p WITH (nolock) INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (nolock) ON p.[object_id] = qs.[object_id] WHERE qs.database_id = Db_id() AND qs.total_physical_reads > 0 ORDER BY qs.total_physical_reads DESC, qs.total_logical_reads DESC OPTION (recompile); |
This helps you find the most
expensive cached stored procedures from a read I/O perspective.You should look
at this if you see signs of I/O pressure or of memory pressure.
Query 11
Top Cached SPs By Total Logical Writes(SP Logical Writes). Logical writes relate to both memory and disk I/O pressure.
SELECT TOP(25) p.NAME AS [SP Name], qs.total_logical_writes AS [TotalLogicalWrites], qs.total_logical_writes / qs.execution_count AS [AvgLogicalWrites], qs.execution_count, Isnull(qs.execution_count / Datediff(minute, qs.cached_time,Getdate()), 0) AS [Calls/Minute], qs.total_elapsed_time, qs.total_elapsed_time / qs.execution_count AS [avg_elapsed_time], qs.cached_time FROM sys.procedures AS p WITH (nolock) INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (nolock) ON p.[object_id] = qs.[object_id] WHERE qs.database_id = Db_id() AND qs.total_logical_writes > 0 ORDER BY qs.total_logical_writes DESC OPTION (recompile); |
This helps you find the most
expensive cached stored procedures from a read I/O perspective.You should look
at this if you see signs of I/O pressure or of memory pressure.
Query 12
Lists the top statements by average input/output usage for the current database(Top IO Statements)
SELECT TOP(50) Object_name(qt.objectid, dbid) AS [SP Name], ( qs.total_logical_reads + qs.total_logical_writes ) / qs.execution_count AS [Avg IO], qs.execution_count AS [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 [Query Text] FROM sys.dm_exec_query_stats AS qs WITH (nolock) CROSS apply sys.Dm_exec_sql_text(qs.sql_handle) AS qt WHERE qt.[dbid] = Db_id() ORDER BY [avg io] DESC OPTION (recompile); |
Helps you find the most expensive
statements for I/O by SP.
Query 13
Possible Bad NC Indexes (writes > reads)(Bad NC Indexes)
SELECT Object_name(s.[object_id]) AS [Table Name], i.NAME AS [Index Name], i.index_id, i.is_disabled, i.is_hypothetical, i.has_filter, i.fill_factor, user_updates AS [Total Writes], user_seeks + user_scans + user_lookups AS [Total Reads], user_updates - ( user_seeks + user_scans + user_lookups ) AS [Difference] FROM sys.dm_db_index_usage_stats AS s WITH (nolock) INNER JOIN sys.indexes AS i WITH (nolock) ON s.[object_id] = i.[object_id] AND i.index_id = s.index_id WHERE Objectproperty(s.[object_id], 'IsUserTable') = 1 AND s.database_id = Db_id() AND user_updates > ( user_seeks + user_scans + user_lookups ) AND i.index_id > 1 ORDER BY [difference] DESC, [total writes] DESC, [total reads] ASC OPTION (recompile); |
Look for indexes with high numbers
of writes and zero or very low numbers of reads.Consider your complete
workload, and how long your instance has been running.Investigate further
before dropping an index!
Query 14
Missing Indexes for current database by Index Advantage(Missing Indexes)
SELECT DISTINCT CONVERT(DECIMAL(18, 2), user_seeks * avg_total_user_cost * ( avg_user_impact * 0.01 ) AS [index_advantage], migs.last_user_seek, mid.[statement] AS [Database.Schema.Table], mid.equality_columns, mid.inequality_columns, mid.included_columns, migs.unique_compiles, migs.user_seeks, migs.avg_total_user_cost, migs.avg_user_impact, Object_name(mid.[object_idAS [Table Name], p.rows AS [Table Rows] FROM sys.dm_db_missing_index_group_stats AS migs WITH (nolock) INNER JOIN sys.dm_db_missing_index_groups AS mig WITH (nolock) ON migs.group_handle = mig.index_group_handle INNER JOIN sys.dm_db_missing_index_details AS mid WITH (nolock) ON mig.index_handle = mid.index_handle INNER JOIN sys.partitions AS p WITH (nolock)ON p.[object_id] = mid.[object_id] WHERE mid.database_id = Db_id() |
Look at index advantage, last user
seek time,number of user seeks to help determine source and importance.SQL
Server is overly eager to add included columns, so beware.Do not just blindly
add indexes that show up from this query!!!
Query 15
Find missing index warnings for cached plans inthe current database(Missing IndexWarnings)Note: This query could take some time on a busy instance.
SELECT TOP(25) Object_name(objectid) AS [ObjectName], query_plan, cp.objtype, cp.usecounts, cp.size_in_bytes FROM sys.dm_exec_cached_plans AS cp WITH (nolock) CROSS apply sys.Dm_exec_query_plan(cp.plan_handle) AS qp WHERE Cast(query_plan AS NVARCHAR(max)) LIKE N'%MissingIndex%' AND dbid = Db_id() ORDER BY cp.usecounts DESC OPTION (recompile); |
Helps you connect missing indexes to specific stored procedures or queries.This
can help you decide whether to add them or not.
Query 16
Breaks down buffers used by current database by object (table, index) in the buffer cache(Buffer Usage)Note: This query could take some time on a busy instance
SELECT Object_name(p.[object_id]) AS [Object Name], p.index_id, Cast(Count(*) / 128.0 AS DECIMAL(10, 2)) AS [Buffer size(MB)], Count(*) AS [BufferCount], p.rows AS [Row Count], p.data_compression_desc AS [Compression Type] FROM sys.allocation_units AS a WITH (nolock) INNER JOIN sys.dm_os_buffer_descriptors AS b WITH (nolock) ON a.allocation_unit_id = b.allocation_unit_id INNER JOIN sys.partitions AS p WITH (nolock) ON a.container_id = p.hobt_id WHERE b.database_id = CONVERT(INT, Db_id()) AND p.[object_id] > 100 GROUP BY p.[object_id], p.index_id, p.data_compression_desc, p.[rows] ORDER BY [buffercount] DESC OPTION (recompile); |
Tells you what tables and indexes
are using the most memory in the buffer cache.It can help identify possible
candidates for data compression.
Query 17
Get Table names, row counts, and
compression status for clustered index or heap (Table Sizes)
SELECT Object_name(object_id) AS [ObjectName], Sum(rows) AS [RowCount], data_compression_desc AS [CompressionType] FROM sys.partitions WITH (nolock) WHERE index_id < 2 --ignore the partitions from the non-clustered index if any AND Object_name(object_id) NOT LIKE N'sys%' AND Object_name(object_id) NOT LIKE N'queue_%' AND Object_name(object_id) NOT LIKE N'filestream_tombstone%' AND Object_name(object_id) NOT LIKE N'fulltext%' AND Object_name(object_id) NOT LIKE N'ifts_comp_fragment%' AND Object_name(object_id) NOT LIKE N'filetable_updates%' AND Object_name(object_id) NOT LIKE N'xml_index_nodes%' AND Object_name(object_id) NOT LIKE N'sqlagent_job%' AND Object_name(object_id) NOT LIKE N'plan_persist%' GROUP BY object_id, data_compression_desc ORDER BY Sum(rows) DESC OPTION (recompile); |
Gives you an idea of table sizes,
and possible data compression opportunities.
Query 18
Get some key table properties(Table Properties)
SELECT Object_name(t.[object_id]) AS [ObjectName], p.[rows] AS [Table Rows], p.index_id, p.data_compression_desc AS [Index Data Compression], t.create_date, t.lock_on_bulk_load, t.is_replicated, t.has_replication_filter, t.is_tracked_by_cdc, t.lock_escalation_desc, t.is_memory_optimized, t.durability_desc, t.is_filetable, t.temporal_type_desc, t.is_remote_data_archive_enabled, t.remote_data_archive_migration_state_desc, t.is_external -- new for SQL Server 2016 FROM sys.tables AS t WITH (nolock) INNER JOIN sys.partitions AS p WITH (nolock) ON t.[object_id] = p.[object_id] WHERE Object_name(t.[object_id]) NOT LIKE N'sys%' ORDER BY Object_name(t.[object_id]), p.index_id OPTION (recompile); |
Gives you some good information
about your tables.Is Memory optimized and durability description are
Hekaton-related properties that were new in SQL Server
2014.temperal_type_desc,is_remote_data_archive_enabled,remote_data_archive_migration_state_desc,is_external
are new in SQL Server 2016.
Query 19
When were Statistics last updated on all indexes?(Statistics Update)
SELECT Schema_name(o.schema_id) + N'.' + o.NAME AS [Object Name], o.type_desc AS [Object Type], i.NAME AS [Index Name], Stats_date(i.[object_id], i.index_id) AS [Statistics Date], s.auto_created, s.no_recompute, s.user_created, s.is_incremental, s.is_temporary, st.row_count, st.used_page_count FROM sys.objects AS o WITH (nolock) INNER JOIN sys.indexes AS i WITH (nolock) ON o.[object_id] = i.[object_id] INNER JOIN sys.stats AS s WITH (nolock) ON i.[object_id] = s.[object_id] AND i.index_id = s.stats_id INNER JOIN sys.dm_db_partition_stats AS st WITH (nolock) ON o.[object_id] = st.[object_id] AND i.[index_id] = st.[index_id] WHERE o.[type] IN ( 'U', 'V' ) AND st.row_count > 0 ORDER BY Stats_date(i.[object_id], i.index_id) DESC OPTION (recompile); |
Helps discover possible problems
with out-of-date statistics.Also gives you an idea which indexes are the most
active.
Query 20
Look at most frequently modified indexes and statistics(Volatile Indexes)
SELECT o.NAME AS [Object Name], o.[object_id], o.type_desc, s.NAME AS [Statistics Name], s.stats_id, s.no_recompute, s.auto_created, sp.modification_counter, sp.rows, sp.rows_sampled, sp.last_updated FROM sys.objects AS o WITH (nolock) INNER JOIN sys.stats AS s WITH (nolock) ON s.object_id = o.object_id CROSS apply sys.Dm_db_stats_properties(s.object_id, s.stats_id) AS sp WHERE o.type_desc NOT IN ( N'SYSTEM_TABLE', N'INTERNAL_TABLE' ) AND sp.modification_counter > 0 ORDER BY sp.modification_counter DESC, o.NAME OPTION (recompile); |
Query 21
Get fragmentation info for all
indexes above a certain size in the current database ( Index Fragmentation)
Note: This query could take some time on a very large database
SELECT Db_name(ps.database_id) AS [Database Name], Schema_name(o.[schema_id]) AS [Schema Name], Object_name(ps.object_id) AS [Object Name], i.NAME AS [Index Name], ps.index_id, ps.index_type_desc, ps.avg_fragmentation_in_percent, ps.fragment_count, ps.page_count, i.fill_factor, i.has_filter, i.filter_definition, i.allow_page_locks FROM sys.Dm_db_index_physical_stats(Db_id(), NULL, NULL, NULL, N'LIMITED') AS ps INNER JOIN sys.indexes AS i WITH (nolock) ON ps.[object_id] = i.[object_id] AND ps.index_id = i.index_id INNER JOIN sys.objects AS o WITH (nolock) ON i.[object_id] = o.[object_id] WHERE ps.database_id = Db_id() AND ps.page_count > 2500 ORDER BY ps.avg_fragmentation_in_percent DESC OPTION (recompile); |
Helps determine whether you have
framentation in your relational indexes and how effective your index
maintenance strategy.
Query 22
Index Read/Write stats (all tables in current DB) ordered by Reads (Overall Index Usage - Reads)
SELECT Object_name(i.[object_id]) AS [ObjectName], i.NAME AS [IndexName], i.index_id, s.user_seeks, s.user_scans, s.user_lookups, s.user_seeks + s.user_scans + s.user_lookups AS [Total Reads], s.user_updates AS [Writes], i.type_desc AS [Index Type], i.fill_factor AS [Fill Factor], i.has_filter, i.filter_definition, s.last_user_scan, s.last_user_lookup, s.last_user_seek FROM sys.indexes AS i WITH (nolock) LEFT OUTER JOIN sys.dm_db_index_usage_stats AS s WITH (nolock) ON i.[object_id] = s.[object_id] AND i.index_id = s.index_id AND s.database_id = Db_id() WHERE Objectproperty(i.[object_id], 'IsUserTable') = 1 ORDER BY s.user_seeks + s.user_scans + s.user_lookups DESC OPTION (recompile); -- Order by reads |
Show which indexes in the current
database are most active for Writes
Query 23
Get in-memory OLTP index usage(XTP
Index Usage)
SELECT Object_name(i.[object_id]) AS [Object Name], i.index_id, i.NAME, i.type_desc, xis.scans_started, xis.scans_retries, xis.rows_touched, xis.rows_returned FROM sys.dm_db_xtp_index_stats AS xis WITH (nolock) INNER JOIN sys.indexes AS i WITH (nolock) ON i.[object_id] = xis.[object_id] AND i.index_id = xis.index_id ORDER BY Object_name(i.[object_id]) OPTION (recompile); |
This gives you some index usage
statistics for in-memory OLTP.Returns no data if you are not using in-memory
OLTP.
Query 24
Get lock waits for current database(Lock Waits)
SELECT o.NAME AS [table_name], i.NAME AS [index_name], ios.index_id, ios.partition_number, Sum(ios.row_lock_wait_count) AS [total_row_lock_waits], Sum(ios.row_lock_wait_in_ms) AS [total_row_lock_wait_in_ms], Sum(ios.page_lock_wait_count) AS [total_page_lock_waits], Sum(ios.page_lock_wait_in_ms) AS [total_page_lock_wait_in_ms], Sum(ios.page_lock_wait_in_ms) + Sum(row_lock_wait_in_ms) AS [total_lock_wait_in_ms] FROM sys.Dm_db_index_operational_stats(Db_id(), NULL, NULL, NULL) AS ios INNER JOIN sys.objects AS o WITH (nolock) ON ios.[object_id] = o.[object_id] INNER JOIN sys.indexes AS i WITH (nolock) ON ios.[object_id] = i.[object_id] AND ios.index_id = i.index_id WHERE o.[object_id] > 100 GROUP BY o.NAME, i.NAME, ios.index_id, ios.partition_number HAVING Sum(ios.page_lock_wait_in_ms) + Sum(row_lock_wait_in_ms) > 0 ORDER BY total_lock_wait_in_ms DESC OPTION (recompile); |
This query is helpful for
troubleshooting blocking and deadlocking issues.
Query 25
Look at UDF execution statistics(UDF Statistics)
SELECT Object_name(object_id) AS [Function Name], execution_count, total_elapsed_time / 1000 AS [time_milliseconds], fs.[type_desc] FROM sys.dm_exec_function_stats AS fs WITH (nolock) WHERE database_id = Db_id() ORDER BY Object_name(object_id) OPTION (recompile); |
New for SQL Server 2016: Helps you investigate UDF Performance Issues
Query 26
Get QueryStore Options for this database(QueryStoreOptions)
SELECT actual_state, actual_state_desc, readonly_reason, current_storage_size_mb, max_storage_size_mb FROM sys.database_query_store_options WITH (nolock) OPTION (recompile); |
New for SQL Server 2016 : Requires that QueryStore is enabled for this database.
Query 27
Get highest aggregate duration queries over last hour (High Aggregate Duration Queries)
WITH aggregateddurationlasthour AS (SELECT q.query_id, Sum(count_executions * avg_duration) AS total_duration, Count (DISTINCT p.plan_id) AS number_of_plans FROM sys.query_store_query_text AS qt WITH (nolock) INNER JOIN sys.query_store_query AS q WITH (nolock) ON qt.query_text_id = q.query_text_id INNER JOIN sys.query_store_plan AS p WITH (nolock) ON q.query_id = p.query_id INNER JOIN sys.query_store_runtime_stats AS rs WITH (nolock) ON rs.plan_id = p.plan_id INNER JOIN sys.query_store_runtime_stats_interval AS rsi WITH ( nolock ) ON rsi.runtime_stats_interval_id = rs.runtime_stats_interval_id WHERE rsi.start_time >= Dateadd(hour, -1, Getutcdate()) AND rs.execution_type_desc = N'Regular' GROUP BY q.query_id), orderedduration AS (SELECT query_id, total_duration, number_of_plans, Row_number () OVER ( ORDER BY total_duration DESC, query_id) AS RN FROM aggregateddurationlasthour) SELECT Object_name(q.object_id) AS [Containing Object], qt.query_sql_text, od.total_duration AS [Total Duration (microsecs)], od.number_of_plans AS [Plan Count], p.is_forced_plan, p.is_parallel_plan, p.is_trivial_plan, q.query_parameterization_type_desc, p.[compatibility_level], p.last_compile_start_time, q.last_execution_time, CONVERT(XML, p.query_plan) AS query_plan_xml FROM orderedduration AS od INNER JOIN sys.query_store_query AS q WITH (nolock) ON q.query_id = od.query_id INNER JOIN sys.query_store_query_text AS qt WITH (nolock) ON q.query_text_id = qt.query_text_id INNER JOIN sys.query_store_plan AS p WITH (nolock) ON q.query_id = p.query_id WHERE od.rn <= 50 ORDER BY total_duration DESC OPTION (recompile); |
New for SQL Server
2016:Requires that QueryStore is enabled for this database.
Query 28
Look at recent Full backups for the current database(Recent Full Backups)
SELECT TOP (30) bs.machine_name, bs.server_name, bs.database_name AS [Database Name], bs.recovery_model, CONVERT (BIGINT, bs.backup_size / 1048576) AS [Uncompressed Backup Size (MB)], CONVERT (BIGINT, bs.compressed_backup_size / 1048576) AS [Compressed Backup Size (MB)], CONVERT (NUMERIC (20, 2), ( CONVERT (FLOAT, bs.backup_size) / CONVERT (FLOAT, bs.compressed_backup_size) )) AS [Compression Ratio], bs.has_backup_checksums, bs.is_copy_only, bs.encryptor_type, Datediff (second, bs.backup_start_date, bs.backup_finish_date) AS [Backup Elapsed Time (sec)], bs.backup_finish_date AS [Backup Finish Date] FROM msdb.dbo.backupset AS bs WITH (nolock) WHERE bs.database_name = Db_name(Db_id()) AND bs.[type] = 'D' -- Change to L if you want Log backups ORDER BY bs.backup_finish_date DESC OPTION (recompile); |
Are your backup sizes
and times changing over time? Are you using backup compression?Have you done
any backup tuning with striped backups, or changing the parameters of the
backup command?
Years of Experience
Gratified Students
Training Batches
Training Hours
Please subscribe our technical blog to get recent updates.