Consider these two queries that get the names of triggers dependant on the JV_VoyageFlight
column in table dbo.JobVoyage
.
the first uses the 'old' mechanism that is deprecated (sys.sql_dependencies
).
SELECT
depObj.name
FROM
sys.sql_dependencies dep
INNER JOIN sys.tables tab ON tab.object_id = dep.referenced_major_id
INNER JOIN sys.schemas sch ON sch.schema_id = tab.schema_id
INNER JOIN sys.columns col ON col.object_id = dep.referenced_major_id AND col.column_id = dep.referenced_minor_id
INNER JOIN sys.objects depObj ON depObj.object_id = dep.object_id
WHERE
sch.name = 'dbo'
AND tab.name = 'JobVoyage'
AND col.name = 'JV_VoyageFlight'
AND depObj.type = 'TR';
The suggested replacement view is sys.sql_expression_dependencies
but this does not contain column level dependencies for non schema bound objects and the documentation advises to use the sys.dm_sql_referenced_entities
function instead for that.
The second query uses the new mechanism.
select distinct name from sys.triggers
cross apply sys.dm_sql_referenced_entities('dbo.' + object_name(object_id), 'object')
where
parent_Class = 1
and Is_Ms_Shipped = 0
and referenced_entity_Name = 'JobVoyage'
and referenced_minor_name = 'JV_VoyageFlight'
One takes 3 milliseconds. One takes 3000 milliseconds.
Does anyone have a better version of this query to get dependencies out of triggers without using deprecated functionality?
Best Answer
I tried this rewrite that uses a temp table with the new DMF on AdventureWorks2014, and it runs around twice as fast as the version from your question.
Here's a screenshot of the Plan Explorer summary after running both queries in the same batch (plans here):
The original query (the first row) runs for about 8 ms, the temp table version (the second two rows) varies between 4 and 5 ms. Of course, your database might have vastly more triggers, objects, and dependencies than AW2014.
As Dan Guzman mentioned, you may also get some improvements by updating system table stats.
FYI - those two queries are not exactly equivalent. The second query will not show the same results if there is a trigger in a different (non-dbo) schema that references
dbo.JobVoyage.JV_VoyageFlight
.In the example query from my test, there is a trigger in the
Sales
schema (iduSalesOrderDetail
) that is returned by the deprecated view but not the DMF version, because the column I'm checking for is in thePerson
schema:If all your objects are in "dbo" then this won't matter, but I thought it was worth pointing out.