Site icon Software Reviews, Opinions, and Tips – DNSstuff

Does Your Database Have Trust Issues?

You probably know someone with trust issues, but do you know if your database has trust issues? In other words, does your database have Check Constraints and Foreign Keys that are not trusted? If so, it’s important to realize that SQL Server may not be able to use them for query plans and optimization, which can in turn affect the performance of your queries. Check Constraints and Foreign Keys that were disabled, perhaps for bulk loading of data, and then enabled again, are no longer trustworthy to SQL Server. As a result, tables must be altered for those Check Constraints and Foreign Keys to earn SQL Server’s trust again.

Custom Conditions

It probably seems like I am always mentioning SQL Sentry Custom Conditions, and perhaps I am. In fact, Custom Conditions are the reason I am writing this blog post. In the next Custom Conditions Pack, there are conditions created from the “Check Constraints: Objects Not Trusted by Database Count” and “Foreign Keys: Objects Not Trusted by Database Count” scripts (below) to help you stay on top of these potential performance issues across your SQL Sentry monitored databases. As a matter of fact, the next pack will be published in only a couple of weeks, and there are numerous new conditions in it!

Performance Impact

Trust Issues Hurting Performance?

To begin with, this post by Sarvesh Singh has a great example of how the performance is impacted. Since that is worthy of its own long blog post, I’ll refer you there for the details.

Next, I set up a very similar quick example using a DogOwners and Dogs table (because if you haven’t noticed, I am a dog person!) and used SQL Sentry Plan Explorer to explore the differences in execution.

reads. Due to the Foreign Key being turned off, the total logical reads increases from just 2 to 202!

Check Constraints

The scripts below will show you how to discover which databases have trust issues with Check Constraints, which specific Check Constraints are not trusted, and how you can fix them.

Check Constraints not Trusted:

First, let’s looks for all databases on an instance with trust issues regarding Check Constraints:

DECLARE @sql nvarchar(max);
SET @sql = N'';
SELECT @sql = @sql + N'UNION ALL 
  SELECT DBName = N''' 
   + name 
   + ''' COLLATE Latin1_General_BIN, 
  CCsNotTrusted =  
  (
    SELECT COUNT(*) AS CCsNotTrusted
      FROM ' + QUOTENAME(name) 
      + '.sys.check_constraints AS c'
      + N' WHERE c.is_not_trusted = 1 
        AND c.is_not_for_replication = 0 
        AND c.is_disabled = 0
  )
  ' FROM sys.databases 
WHERE database_id > 4 AND state = 0;
 
SET @sql = N'SELECT DBName, CCsNotTrusted FROM 
(' + STUFF(@sql, 1, 10, N'') 
   + N') AS x WHERE CCsNotTrusted > 0;';
 
EXEC sys.sp_executesql @sql;

Untrustworthy Check Constraints by Database

Check Constraints: Objects Not Trusted by Database Count

Second, we’ll obtain a list of those specific Check Constraints with trust issues for a database in the above results:

SELECT QUOTENAME(s.name) + N'.' + QUOTENAME(o.name) 
  + N'.' + QUOTENAME(c.name) AS CCsNotTrusted
FROM sys.check_constraints c
INNER JOIN 
sys.objects o ON c.parent_object_id = o.object_id
INNER JOIN 
sys.schemas s ON o.schema_id = s.schema_id
WHERE c.is_not_trusted = 1 
AND c.is_not_for_replication = 0 
AND c.is_disabled = 0
ORDER BY CCsNotTrusted;

Untrustworthy Check Constraints

Check Constraints: Objects Not Trusted

Restoring Trust

Finally, we’ll execute statements to restore trustworthiness to individual Check Constraints:

ALTER TABLE TableName WITH CHECK CHECK CONSTRAINT ConstraintName;

Fix Check Constraints

ALTER TABLE [dbo].[dogs] WITH CHECK CHECK CONSTRAINT [chk_dog_owners];

Fix an Example Constraint

Moreover, you may have many Check Constraints to fix, in which case, you can run this script so that you can generate the necessary T-SQL:

SELECT N'ALTER TABLE ' 
    + QUOTENAME(s.name) + N'.' + QUOTENAME(o.name) 
    + N' WITH CHECK CHECK CONSTRAINT ' 
    + QUOTENAME(c.name) + N';' AS CCsToFix
FROM sys.check_constraints c
INNER JOIN 
sys.objects o ON c.parent_object_id = o.object_id
INNER JOIN 
sys.schemas s ON o.schema_id = s.schema_id
WHERE c.is_not_trusted = 1 
AND c.is_not_for_replication = 0 
AND c.is_disabled = 0
ORDER BY CCsToFix;

Generate Fix Check Constraints Script

Generated Scripts to Fix Check Constraints

Foreign Keys

In addition to check constraints not being trusted, you can have essentially the same problem with foreign key constraints. Likewise, there’s a great video by Kendra Little on the brentozar.com website which provides a detailed explanation of this issue.

Foreign Keys not Trusted:

Again, we’ll first look for all databases on an instance with trust issues, but this time for foreign key constraints.

SELECT QUOTENAME(s.name) + N'.' + QUOTENAME(o.name)
  + N'.' + QUOTENAME(f.name) AS FKsNotTrusted
FROM sys.foreign_keys f
INNER JOIN 
sys.objects o ON f.parent_object_id = o.object_id
INNER JOIN 
sys.schemas s ON o.schema_id = s.schema_id
WHERE f.is_not_trusted = 1 
AND f.is_not_for_replication = 0
ORDER BY FKsNotTrusted;

Untrustworthy Foreign Keys by Database

Foreign Keys: Objects Not Trusted by Database Count

Next, we’ll get a list of affected foreign key constraints from one of the databases in the previous results set:

SELECT QUOTENAME(s.name) + N'.' + QUOTENAME(o.name)
  + N'.' + QUOTENAME(f.name) AS FKsNotTrusted
FROM sys.foreign_keys f
INNER JOIN 
sys.objects o ON f.parent_object_id = o.object_id
INNER JOIN 
sys.schemas s ON o.schema_id = s.schema_id
WHERE f.is_not_trusted = 1 
AND f.is_not_for_replication = 0
ORDER BY FKsNotTrusted;

Untrustworthy Foreign Keys

Foreign Keys: Objects Not Trusted

Restoring Trust

Lastly, we’ll use another query to create a script for restoring trustworthiness to Foreign Keys:

SELECT N'ALTER TABLE ' + QUOTENAME(s.name) 
  + N'.' + QUOTENAME(o.name) + N' WITH CHECK CHECK CONSTRAINT ' 
  + QUOTENAME(f.name) + N';' AS FKstoFix
FROM    sys.foreign_keys f
INNER JOIN 
 sys.objects o ON f.parent_object_id = o.object_id
INNER JOIN 
 sys.schemas s ON o.schema_id = s.schema_id
WHERE f.is_not_trusted = 1 
 AND f.is_not_for_replication = 0
 ORDER BY FKstoFix;

Fix Foreign KeysSummary

As shown above, trust issues in your databases can cause performance issues with poor query plans. Overall, these constraint issues are not difficult to resolve, however, they frequently go unnoticed. Regularly checking for trust issues across your databases via Custom Conditions in SQL Sentry will help you stay ahead of any potential performance issues caused by a lack of trust.