Saturday, February 29, 2020

Check if your dynamic T-SQL statement is valid

Validating SQL Queries with a Stored Procedure in SQL Server

In this post, I will walk you through creating a stored procedure that can be used to validate SQL queries. The procedure checks if the SQL query is syntactically correct and can be executed successfully without any errors.

The stored procedure I'll show you is designed to check if a query can run without any issues by parsing it first before execution.

Here’s the SQL code for the stored procedure:

CREATE PROCEDURE IsValidSQLs (@sql VARCHAR(MAX))
AS
BEGIN
    BEGIN TRY
        SET @sql = 'SET PARSEONLY ON;' + @sql;
        EXECUTE(@sql);
    END TRY
    BEGIN CATCH
        RETURN(0); -- Failure
    END CATCH;
    RETURN(1); -- Success
END; -- IsValidSQLs

Testing the Procedure

To test the procedure, let's try a scenario where we know the query will fail. In this example, we're referencing a non-existent table called T:

-- Fail Scenario
DECLARE @retval INT;
EXECUTE @retval = IsValidSQLs 'SELECT IIF(val, 0, 1) FROM T'; -- T does not exist
SELECT @retval;
GO

When executed, this query will return 0 because the table T doesn't exist in the database.

Success Case

Now, let’s test it with a query that should pass. In this case, we will create a temporary table #T and then try running a query against it:

-- Success Scenario
CREATE TABLE #T(id INT IDENTITY(1,1), val VARCHAR(100));
DECLARE @retval INT;
EXECUTE @retval = IsValidSQLs 'SELECT val FROM #T'; -- #T exists
SELECT @retval;

This time, the procedure will return 1, indicating that the query is valid and syntactically correct.


By using this stored procedure, you can easily validate SQL queries before executing them, ensuring they won’t cause errors in your applications. This can be particularly useful in scenarios where dynamic SQL is being executed.

Get UDF execution statistics

 Get UDF execution statistics

Ever wondered which functions are consuming the most resources in your SQL Server database? The sys.dm_exec_function_stats Dynamic Management View (DMV) is your go-to for uncovering performance bottlenecks within your user-defined functions.

This powerful DMV provides insights into the execution statistics of cached functions, helping you identify those that are frequently called, take a long time to complete, or consume a lot of CPU time.

Here's a handy SQL query to retrieve the top 25 functions by total worker time, giving you a quick overview of potential performance hogs:

SELECT TOP (25) 
    DB_NAME(database_id) AS [Database Name],
    OBJECT_NAME(object_id, database_id) AS [Function Name],
    total_worker_time,
    execution_count,
    total_elapsed_time,
    total_elapsed_time / execution_count AS [avg_elapsed_time],
    last_elapsed_time,
    last_execution_time,
    cached_time,
    [type_desc]
FROM sys.dm_exec_function_stats WITH (NOLOCK)
ORDER BY total_worker_time DESC
OPTION (RECOMPILE);

This query pulls crucial metrics like the function's name, the database it belongs to, the total CPU time it has consumed (total_worker_time), how many times it's been executed (execution_count), and its average and last elapsed times. The OPTION (RECOMPILE) ensures that the query plan is recompiled each time, helping to get the most up-to-date statistics.

For more in-depth information on sys.dm_exec_function_stats, you can refer to the official Microsoft documentation: sys.dm_exec_function_stats (Transact-SQL)

Optimizing your SQL Server functions can significantly improve your database's overall performance. So go ahead, give this query a spin and see what insights you can uncover!

Sunday, February 23, 2020

Find require /missing index on tables

Identifying and Recommending Missing Indexes for Better SQL Server Performance

When optimizing SQL Server performance, identifying missing indexes can be an effective way to reduce query costs and improve response times. However, analyzing index recommendations can be resource-intensive. It is often best to schedule this analysis during off-peak hours and store the results for further in-depth review.

SQL Query to Detect Missing Indexes

The following SQL query calculates a metric to prioritize potential missing indexes based on their impact and usage. It also generates the recommended CREATE INDEX statements for implementation:


SELECT
    migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
    'CREATE INDEX [IX_' + CONVERT(VARCHAR, mig.index_group_handle) + '_' + CONVERT(VARCHAR, mid.index_handle) + '_' + LEFT(PARSENAME(mid.STATEMENT, 1), 32) + ']' + 
    ' ON ' + mid.STATEMENT + 
    ' (' + ISNULL(mid.equality_columns, '') + 
    CASE 
        WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' 
        ELSE '' 
    END + ISNULL(mid.inequality_columns, '') + ') ' + 
    ISNULL(' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement,
    migs.*,
    mid.database_id,
    mid.[object_id]
FROM
    [sys].dm_db_missing_index_groups AS mig
INNER JOIN 
    [sys].dm_db_missing_index_group_stats AS migs 
    ON migs.group_handle = mig.index_group_handle
INNER JOIN 
    [sys].dm_db_missing_index_details AS mid 
    ON mig.index_handle = mid.index_handle
WHERE
    migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * 
    (migs.user_seeks + migs.user_scans) > 10
ORDER BY 
    migs.avg_total_user_cost * migs.avg_user_impact * 
    (migs.user_seeks + migs.user_scans) DESC;

Why Missing Indexes Matter

Missing indexes can significantly degrade database performance by forcing SQL Server to perform expensive scans instead of efficient seeks. By regularly reviewing and applying index recommendations, you can ensure your database runs smoothly and efficiently, especially under heavy load.

Saturday, February 22, 2020

List objects with space used information

 

Analyzing SQL Server Object Space Usage with sys.dm_db_partition_stats

When working with large databases in SQL Server, understanding how space is utilized by different objects—such as tables and indexes—is crucial for performance tuning and storage planning. One of the most useful tools for this purpose is the system dynamic management view sys.dm_db_partition_stats.

What is sys.dm_db_partition_stats?

The sys.dm_db_partition_stats view provides detailed information about row and page counts for each partition in the current database. This data is essential for determining how much space each object consumes and for differentiating between table data and index data.

You can refer to the official Microsoft documentation here:
🔗 sys.dm_db_partition_stats (Transact-SQL)

Query to List SQL Server Objects with Space Usage

The following SQL query helps you list all user-defined database objects along with the space they use. It breaks down the space into total space used, space used by the table data, and space used by nonclustered indexes.


-- Retrieve space usage details for user-defined objects in the current database
SELECT
    SCHEMA_NAME(o.schema_id) + '.' + OBJECT_NAME(p.object_id) AS [Name],
    CONVERT(decimal(18,2), SUM(reserved_page_count) * 8 / 1024.0) AS Total_space_used_MB,
    CONVERT(decimal(18,2), SUM(CASE WHEN index_id < 2 THEN reserved_page_count ELSE 0 END) * 8 / 1024.0) AS Table_space_used_MB,
    CONVERT(decimal(18,2), SUM(CASE WHEN index_id > 1 THEN reserved_page_count ELSE 0 END) * 8 / 1024.0) AS Nonclustered_index_space_used_MB,
    MAX(row_count) AS Row_count
FROM    
    sys.dm_db_partition_stats AS p
INNER JOIN 
    sys.all_objects AS o ON p.object_id = o.object_id
WHERE
    o.is_ms_shipped = 0
GROUP BY
    SCHEMA_NAME(o.schema_id) + '.' + OBJECT_NAME(p.object_id)
ORDER BY
    Total_space_used_MB DESC;

How This Helps

  • Total_space_used_MB: Gives a combined view of how much space each object is using in megabytes.
  • Table_space_used_MB: Shows how much of that space is allocated to table data (clustered index or heap).
  • Nonclustered_index_space_used_MB: Reflects how much space is used by nonclustered indexes.
  • Row_count: Indicates the number of rows in the object, which helps contextualize the space usage.

This query is particularly helpful when you're diagnosing storage issues or planning to optimize your indexes or database schema.

Saturday, February 8, 2020

Tables with INSTEAD OF triggers

 

Identifying Tables with INSTEAD OF Triggers in SQL Server

In SQL Server, it's sometimes necessary to determine which tables have INSTEAD OF triggers defined on them. These types of triggers override standard actions like INSERT, UPDATE, or DELETE, allowing custom behavior instead of the default database action.

Query to List Tables with INSTEAD OF Triggers

The following SQL query helps you retrieve a list of tables that have at least one INSTEAD OF trigger:

SELECT s.[Name] + N'.' + t.[Name] AS [Table]
FROM [sys].tables t
INNER JOIN [sys].schemas s ON t.[schema_id] = s.[schema_id]
WHERE EXISTS (
  SELECT *
  FROM [sys].triggers tr
  WHERE tr.parent_id = t.[object_id]
    AND tr.is_instead_of_trigger = 1
);

This script joins the sys.tables and sys.schemas system views to display fully qualified table names (i.e., schema.table). It filters for those tables where an INSTEAD OF trigger exists.

Finding Tables Without INSTEAD OF Triggers

If you're looking to find tables without any INSTEAD OF triggers, simply replace EXISTS with NOT EXISTS in the WHERE clause.


Further Reading

Popular Posts