sql视图中未被select引用的列需通过静态分析识别:先解析视图定义获取所有输出列,再扫描所有调用该视图的sql语句提取实际引用的列,二者差集即为“定义了但从未被select过”的列。

SQL视图里哪些列根本没被查到?
靠人工翻代码几乎不可能准确识别——尤其当视图被几十个报表、接口、存储过程引用时。真正可行的路径是:**先提取所有对视图的 SELECT 引用,再逐字段反向追踪是否出现在 SELECT 列表、WHERE、JOIN 或 GROUP BY 中**。工具链不成熟,多数静态分析器(如 SQLFluff、Squid)默认不覆盖视图列粒度依赖,得自己补逻辑。
用 pg_depend 和 pg_attribute 查 PostgreSQL 视图真实使用列
PostgreSQL 的系统目录能暴露视图定义与依赖对象的映射,但注意:pg_depend 只记录“视图依赖哪些基础表/列”,不记录“外部查询用了视图里的哪几列”。所以得两步走:
- 用
pg_get_viewdef('your_view')拿到视图定义 SQL,解析出它 SELECT 了哪些源列(这一步已有列) - 扫描所有可能调用该视图的 SQL(应用代码、函数体、其他视图定义),grep 或 AST 解析找
SELECT.*FROM your_view类模式,再正则提取字段列表(如SELECT a, b, c→ 关注abc) - 把第二步中实际出现的列名,和第一步视图定义里所有输出列取交集;差集就是“定义了但从未被 SELECT 过”的列
别信 pg_stats 或执行计划——那些反映运行时行为,而你要的是编译期/引用期的静态事实。
MySQL / SQL Server 怎么办?没有 pg_depend 怎么办
它们没提供等价的列级依赖视图,只能退到文本扫描 + 语法解析:
- MySQL:导出所有存储过程、函数、事件的
ROUTINE_DEFINITION字段(查information_schema.ROUTINES),再用正则匹配SELECT.*?FROM.*?your_view,配合括号平衡解析提取字段 - SQL Server:查
sys.sql_modules,过滤definition LIKE '%your_view%',然后用 T-SQL 的PARSENAME和字符串拆分模拟字段提取(注意别漏掉SELECT *场景) - 通用坑:
SELECT *必须视为“所有列都被使用”,不能跳过;别忽略 CTE 中的引用(WITH x AS (SELECT * FROM your_view))
AST 解析比正则更可靠,但代价是什么
用 sqlglot(Python)或 js-sql-parser(JS)做语法树遍历,能精准识别字段引用位置,避开别名混淆、嵌套子查询漏判等问题。但代价明显:
- 需要预处理所有 SQL:剥离注释、统一换行、展开变量(如
${table}) -
sqlglot对某些方言(如 HiveQL 的 LATERAL VIEW)支持弱,容易解析失败 - 视图嵌套三层以上时,AST 路径追踪复杂度陡增,容易误判“间接使用”为“未使用”
最常被忽略的一点:视图列如果只在 ORDER BY 或 LIMIT/OFFSET 中出现,**不算被使用**——数据库不会为排序字段申请额外内存或索引,这类列仍应计入“未使用”名单。










