是否有任何理智的方法来捕获SQL Server中的执行时对象依赖项?
例如,采用这种动态SQL方案:
DECLARE @table SYSNAME = 'SomeTable'
DECLARE @column SYSNAME = 'SomeColumn'
DECLARE @proc SYSNAME
DECLARE @command NVARCHAR(MAX) = 'SELECT TOP 1 @proc = '+@column+' FROM '+@table
EXEC sp_executesql @command, N'@proc SYSNAME OUTPUT', @proc OUTPUT
EXEC @proc
执行时依赖性将是SomeTable
,sp_executesql
,@proc
的值,以及@在运行时引用的任何对象程序。
到目前为止我考虑过的方法:
从每个批次中的sys.dm_exec_query_plan中获取xml查询计划,并通过服务代理将其传递给另一个进程进行处理。专业人士:我认为它可能确实有效。缺点:潜在的昂贵和侵入性:必须改进每个批处理和执行级别以捕获查询计划。
扩展事件。专业人士:如果它可以成功,那就太好了!缺点:我认为没有合适的“对象访问”事件类,例如扫描和/或搜索和/或执行等等。
理想情况下,捕获可以像这样工作:
DECLARE @guid UNIQUEIDENTIFIER
EXEC usp_begin_object_capture @guid OUTPUT
DECLARE @table SYSNAME = 'SomeTable'
DECLARE @column SYSNAME = 'SomeColumn'
DECLARE @proc SYSNAME
DECLARE @command NVARCHAR(MAX) = 'SELECT TOP 1 @proc = '+@column+' FROM '+@table
EXEC sp_executesql @command, N'@proc SYSNAME OUTPUT', @proc OUTPUT
EXEC @proc
EXEC usp_stop_object_capture @guid
SELECT object_name FROM object_capture_table WHERE guid = @guid
------------------------------
object_name
------------------------------
SomeTable
sp_executesql
<proc_named_by_@proc>
<object1_referenced_by_@proc>
<object2_referenced_by_@proc>
<object3_referenced_by_@proc>
<objectn_referenced_by_@proc>
背景:
我正在尝试缓存/记忆长时间运行过程的确定性结果集。基础数据相当静态。如果我可以在执行时收集实际依赖项,我可以自动将缓存中的条目与一组对象相关联。如果这些对象中的任何一个发生了变化,我会知道哪些条目无效。
这可能是一个糟糕的缓存策略,我不知道。但依赖技术在其他环境中仍然有用。
有什么想法?非常感谢。
答案 0 :(得分:2)
如何利用SQL Server内置机制进行缓存失效,即Query Notifications?您缓存/记住您的查询结果,并让SQL Server自己在结果发生更改时通知您。
答案 1 :(得分:0)
[回答我自己的问题......]
请参阅sp_trace%system procs,以w / sp_trace_create开头。
使用事件114,“审计架构对象访问事件”。
包括列DatabaseName
,ParentName
和ObjectName
,以及ServerName
。
过滤第12列,SPID
。
扩展事件不会公开架构对象访问事件(否则),否则可能更好。