如何检索SQL视图中查询优化器实际使用的原始列?
获取视图实际被优化器使用的基表列
要得到查询优化器实际执行视图时用到的原始表列(比如你的示例中仅a,c,d),可以通过解析视图的执行计划来实现,以下是具体方案:
方法1:捕获并解析执行计划XML
步骤1:生成视图的执行计划
先执行视图并捕获其执行计划:
SET SHOWPLAN_XML ON; GO SELECT * FROM test.v_test; GO SET SHOWPLAN_XML OFF;
步骤2:从缓存提取计划并解析列引用
执行以下SQL,自动从缓存中提取计划并解析出实际使用的基表列:
DECLARE @plan XML; -- 从缓存获取刚生成的视图执行计划 SELECT @plan = query_plan FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st WHERE st.text LIKE '%SELECT * FROM test.v_test%' AND cp.objtype = 'View'; -- 解析XML提取基表的使用列 SELECT DISTINCT col.value('@Database', 'SYSNAME') AS 数据库名, col.value('@Schema', 'SYSNAME') AS 架构名, col.value('@Table', 'SYSNAME') AS 表名, col.value('@Column', 'SYSNAME') AS 列名 FROM @plan.nodes('//ColumnReference[@Database and @Table]') AS ref(col) WHERE col.value('@Database', 'SYSNAME') = 'test' AND col.value('@Table', 'SYSNAME') = 't_test';
执行后会返回a,c,d这三个实际被优化器使用的列,冗余的b,e不会出现在结果中。
注意事项
- 如果视图从未被执行过,缓存中没有对应的执行计划,需要先手动执行一次视图(比如
SELECT * FROM test.v_test)来生成计划。 - 该方法依赖SQL Server的列裁剪优化逻辑,优化器会自动剔除视图定义中未被最终输出或计算用到的冗余列,所以结果是准确的。
内容的提问来源于stack exchange,提问作者user23733126
相关产品推荐
相关产品推荐

