Unveiling Query Performance Insights: Leveraging T-SQL with SQL Server Query Store

Introduction

In the dynamic realm of database management, monitoring and optimizing query performance is paramount. SQL Server offers the Query Store feature, a powerful tool that captures and stores detailed information about query execution plans and runtime statistics. In this blog post, we’ll delve into leveraging T-SQL to extract valuable insights from the Query Store, focusing on queries executed within the last 7 days.

Query Store Essentials

Before we dive into T-SQL scripts, let’s briefly revisit the Query Store. It acts as a repository for query-related data, allowing database administrators to analyze historical performance metrics and troubleshoot issues efficiently.

Comprehensive Query Analysis in the Last 7 Days

To get a comprehensive view of queries executed in the last 7 days, we can use the following T-SQL script:

-- T-SQL script to analyze queries executed in the last 7 days

SELECT
p.query_id query_id,
q.object_id object_id,
ISNULL(OBJECT_NAME(q.object_id),'') object_name,
qt.query_sql_text query_sql_text,
ROUND(CONVERT(float, SUM(rs.avg_duration*rs.count_executions))*0.001,2) total_duration,
ROUND(CONVERT(float, SUM(rs.avg_cpu_time*rs.count_executions))*0.001,2) total_cpu_time,
ROUND(CONVERT(float, SUM(rs.avg_logical_io_reads*rs.count_executions))*8,2) total_logical_io_reads,
ROUND(CONVERT(float, SUM(rs.avg_physical_io_reads*rs.count_executions))*8,2) total_physical_io_reads,
ROUND(CONVERT(float, SUM(rs.avg_logical_io_writes*rs.count_executions))*8,2) total_logical_io_writes,
SUM(rs.count_executions) count_executions,
COUNT(distinct p.plan_id) num_plans
FROM sys.query_store_runtime_stats rs
JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id
JOIN sys.query_store_query q ON q.query_id = p.query_id
JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
WHERE rs.first_execution_time BETWEEN (getdate()-7) AND (getdate())
GROUP BY p.query_id, qt.query_sql_text, q.object_id
HAVING COUNT(distinct p.plan_id) >= 1
ORDER BY count_executions DESC

This script provides a detailed breakdown of query performance, including execution counts, total duration, CPU time, and more, for queries executed in the last 7 days.

Specific Query Search Example

Suppose you want to focus on queries containing a specific keyword within the last 7 days. The following T-SQL script demonstrates how to achieve this:

-- T-SQL script to search for a specific query in the last 7 days

SELECT
p.query_id query_id,
q.object_id object_id,
ISNULL(OBJECT_NAME(q.object_id),'') object_name,
qt.query_sql_text query_sql_text,
ROUND(CONVERT(float, SUM(rs.avg_duration*rs.count_executions))*0.001,2) total_duration,
ROUND(CONVERT(float, SUM(rs.avg_cpu_time*rs.count_executions))*0.001,2) total_cpu_time,
ROUND(CONVERT(float, SUM(rs.avg_logical_io_reads*rs.count_executions))*8,2) total_logical_io_reads,
ROUND(CONVERT(float, SUM(rs.avg_physical_io_reads*rs.count_executions))*8,2) total_physical_io_reads,
ROUND(CONVERT(float, SUM(rs.avg_logical_io_writes*rs.count_executions))*8,2) total_logical_io_writes,
SUM(rs.count_executions) count_executions,
COUNT(distinct p.plan_id) num_plans
FROM sys.query_store_runtime_stats rs
JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id
JOIN sys.query_store_query q ON q.query_id = p.query_id
JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
WHERE rs.first_execution_time BETWEEN (getdate()-7) AND (getdate())
and qt.query_sql_text LIKE 'DELETE FROM%'
GROUP BY p.query_id, qt.query_sql_text, q.object_id
HAVING COUNT(distinct p.plan_id) >= 1
ORDER BY count_executions DESC

This example narrows down the search to queries with the keyword “DELETE FROM” executed in the last 7 days.

Conclusion

In conclusion, harnessing the power of T-SQL with the SQL Server Query Store provides a robust way to analyze and optimize query performance. The provided scripts offer a starting point for gaining valuable insights into the queries executed in the last 7 days, enabling proactive database management and performance tuning.

Stay tuned for more in-depth explorations of SQL Server features and best practices!

Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided β€œAS IS” with no warranties, and confers no rights.

Exploring Always On Availability Replica Details and Database Health

Introduction πŸš€

Maintaining the health and performance of your SQL Server Availability Groups (AG) is essential for a resilient database infrastructure. In this blog post, we’ll delve into a T-SQL script designed to retrieve detailed information about your AG replicas and the associated database health. This script provides a comprehensive overview of key metrics, allowing database administrators to monitor and ensure the robustness of their AG configurations.

Requirements πŸ› οΈ

Before using the T-SQL script, ensure that the following requirements are met:

  1. SQL Server Availability Groups: The script is designed for environments with configured Availability Groups.
  2. Permissions: The account executing the script should have sufficient permissions to query the necessary dynamic management views.

T-SQL Script πŸ“œ

Use the following T-SQL script to obtain detailed information about your AG replicas and database health:

SELECT 

ar.replica_server_name,
adc.database_name,
ag.name AS ag_name,
CASE HDRS.is_primary_replica
WHEN 1 THEN 'Primary Replica'
ELSE 'Secondary Replica'
END AS Replica,
HDRS.synchronization_state_desc,
HDRS.synchronization_health_desc,
HDRS.recovery_lsn,
HDRS.truncation_lsn,
HDRS.last_sent_lsn,
HDRS.last_sent_time,
HDRS.last_received_lsn,
HDRS.last_received_time,
HDRS.last_hardened_lsn,
HDRS.last_hardened_time,
HDRS.last_redone_lsn,
HDRS.last_redone_time,
HDRS.log_send_queue_size,
HDRS.log_send_rate,
HDRS.redo_queue_size,
HDRS.redo_rate,
HDRS.filestream_send_rate,
HDRS.end_of_log_lsn,
HDRS.last_commit_lsn,
HDRS.last_commit_time
FROM sys.dm_hadr_database_replica_states AS HDRS
INNER JOIN sys.availability_databases_cluster AS adc
ON HDRS.group_id = adc.group_id AND
HDRS.group_database_id = adc.group_database_id
INNER JOIN sys.availability_groups AS ag
ON ag.group_id = HDRS.group_id
INNER JOIN sys.availability_replicas AS ar
ON HDRS.group_id = ar.group_id AND
HDRS.replica_id = ar.replica_id

This script combines data from various system views to present a holistic view of your AG configuration and the health status of associated databases.

Conclusion πŸŽ‰

Effectively managing your SQL Server Availability Groups involves not only understanding the configuration details but also regularly monitoring the health of replicas and databases. By utilizing the provided T-SQL script, database administrators can proactively identify and address potential issues, ensuring the continuous availability and reliability of their databases.

Regularly run this script and incorporate the insights gained into your monitoring routine to keep your SQL Server environment robust and resilient. May your databases always be available and your replicas in sync! πŸ’ͺ

Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided β€œAS IS” with no warranties, and confers no rights.

Performing Always On Availability Group Health Check for a Single Database

Introduction 🌐

Always On Availability Groups (AG) in SQL Server provide high availability and disaster recovery solutions for databases. Ensuring the health of your AG is crucial to maintaining a resilient database environment. In this blog post, we’ll guide you through a T-SQL script that performs a comprehensive health check for a single database within an AG. This script will be executed on the primary replica and includes valuable information such as synchronization state, database state, and secondary lag in seconds.

Requirements πŸ› οΈ

Before diving into the health check script, make sure you meet the following prerequisites:

  1. SQL Server Availability Group: Ensure that your SQL Server instance is configured with an Availability Group containing the target database.
  2. Permission: The account executing the script should have the necessary permissions to query the sys.dm_hadr_database_replica_states dynamic management view.
  3. Primary Replica: Run the script on the primary replica of the Availability Group.

T-SQL Script πŸ“œ

Here’s the T-SQL script that will provide a detailed health check for a specific database within your Availability Group:

select 

db_name(database_id) as [Database],
is_primary_replica,
synchronization_state_desc,
database_state_desc,
is_suspended,
suspend_reason_desc,
recovery_lsn,
truncation_lsn,
last_sent_lsn,
last_sent_time,
last_received_lsn,
last_received_time,
last_hardened_lsn,
log_send_queue_size,
log_send_rate,
redo_queue_size,
redo_rate,
end_of_log_lsn,
last_commit_lsn,
last_commit_time,
secondary_lag_seconds
from
sys.dm_hadr_database_replica_states

This script retrieves essential information about the specified database, such as synchronization state, log queue details, and secondary replica lag in seconds.

Conclusion πŸŽ‰

Regularly monitoring the health of your Always On Availability Group is fundamental to ensuring the stability and reliability of your SQL Server databases. By utilizing the provided T-SQL script, you can quickly assess the state of a single database within the AG, identify any potential issues, and take proactive measures to maintain a robust database infrastructure.

Remember to schedule periodic health checks to catch any anomalies early, minimizing the risk of downtime and data loss in your SQL Server environment. Stay vigilant, and may your databases always be available and resilient! πŸ’ͺ

Thank You,
Vivek Janakiraman

Disclaimer:
The views expressed on this blog are mine alone and do not reflect the views of my company or anyone else. All postings on this blog are provided β€œAS IS” with no warranties, and confers no rights.