如何排查查询重写Query Rewrite不生效_参数设置、统计信息与约束完整性检查

星墨姑娘_7622

星墨姑娘_7622

2026-03-20

411人浏览

原创

根本原因是规则匹配失败而非规则错误,因重写发生在parse后、plan前,仅作用于原始语法树,不感知视图展开或优化器改写。

为什么 pg_rewrite 或查询重写规则没触发

根本原因通常是规则匹配失败,而不是规则本身写错了。postgresql 的查询重写在 parse 阶段后、plan 阶段前执行,只作用于原始语法树,不感知视图展开、cte 提取或优化器改写后的形式。

常见错误现象:SELECT * FROM old_table 没被重写成 SELECT * FROM new_table;或者重写后报错 relation "new_table" does not exist(说明规则生效了,但目标对象不可见)。

  • 确保规则定义在正确 schema 下,且当前 search_path 包含该 schema
  • 规则只能重写 SELECT/INSERT/UPDATE/DELETE,不能重写 WITH 子句内部的查询
  • 如果原查询带 FOR UPDATE 或行级锁,重写目标必须支持相同锁定语义,否则静默跳过
  • 用 \dR+ 查看规则是否启用(Enabled 列为 O 表示 on),禁用状态不会触发

pg_statistic 和统计信息对重写有影响吗

没有直接影响。查询重写发生在优化器介入之前,完全不读取 pg_statistic,也不依赖任何统计信息或直方图。

但容易混淆的点在于:你可能误以为「重写后查询变慢」是重写问题,实际是重写目标表(比如新分区表)缺少统计信息,导致后续执行计划劣化。这时 ANALYZE 有用,但跟重写机制无关。

  • 重写是否生效,看 EXPLAIN 输出里是否出现目标表名,而不是看执行时间
  • 若重写后 EXPLAIN 显示扫描了 new_table 却很慢,先 ANALYZE new_table,再对比 EXPLAIN (ANALYZE)
  • 不要在重写规则里引用尚未 ANALYZE 过的表——不是语法错误,但会误导你怀疑重写失效

外键、NOT NULL、CHECK 约束会阻止重写生效吗

不会。约束检查发生在重写之后的执行阶段,不影响重写规则是否被应用。

真正会中断流程的是:重写生成的新查询本身语法/语义不合法。比如原查询 SELECT a,b FROM t 被重写为 SELECT x,y,z FROM u,而列数不匹配或类型无法隐式转换,就会在重写后校验时报错 column "z" does not exist,看起来像“没生效”,其实是“生效了但挂了”。

  • 用 EXPLAIN (VERBOSE) 看重写结果:输出中 Output: 和 Relation Name: 会暴露最终访问的表和列
  • 如果目标表有 NOT NULL 列,而重写后的 INSERT 没提供值,错误发生在执行期,不是重写期
  • 跨 schema 重写时,注意目标表的权限:重写不检查权限,但执行时会报 permission denied for table new_table

如何确认重写是否真正在生产中起作用

不能只靠日志或 EXPLAIN 一次就下结论。真实负载下,连接、事务隔离级别、prepared statement 缓存都会干扰判断。

最可靠的方式是结合 pg_stat_statements 和手工注入标记。比如在重写规则里把 SELECT 改成 SELECT 'rewritten'::text AS marker, *,然后查 pg_stat_statements 里是否出现带该 marker 的 queryid。

  • 临时开启 log_statement = 'mod' 并过滤关键词 rewritten,比盲猜更直接
  • 避免用 PREPARE + EXECUTE 测试:预编译语句在 parse 阶段完成,重写只对原始文本生效,预编译后无法再触发
  • 如果用了连接池(如 pgbouncer),确认它没开启 transaction 池化模式——该模式下 parse 可能被复用,导致重写失效

重写机制本身很简单,复杂点全在边界:schema 可见性、权限继承链、prepare 生命周期、以及你误把执行期错误当成重写失败。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
大数据分析工具有哪四个
大数据分析工具有哪四个

大数据分析的四个工具分别是rapidminer、Hpcc、Hadoop和Pentaho bi。大数据分析用于从各种来源生成的原始数据中提取有价值的数据。这些数据帮助我们获得有意义的见解、隐藏的模式、未知的相关性、市场趋势等等,具体取决于行业。大数据分析的主要动机是提供有价值的见解,以便为未来做出更好的决策。php中文网为大家带来了大数据分析的相关教程、以及相关文章等内容,供大家免费下载使用。

2023.06.21

4956

5

Java 大数据处理基础(Hadoop 方向)
Java 大数据处理基础(Hadoop 方向)

本专题聚焦 Java 在大数据离线处理场景中的核心应用,系统讲解 Hadoop 生态的基本原理、HDFS 文件系统操作、MapReduce 编程模型、作业优化策略以及常见数据处理流程。通过实际示例(如日志分析、批处理任务),帮助学习者掌握使用 Java 构建高效大数据处理程序的完整方法。

2025.12.08

1249

12

大数据专业学习教程
大数据专业学习教程

本专题整合了大数据专业学习相关教程,阅读专题下面的文章了解更多详细内容。

2026.01.05

243

5

python处理大数据合集
python处理大数据合集

本专题整合了python处理大数据相关教程,阅读专题下面的文章了解更多详细内容。

2026.01.05

466

22

数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4223

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

891

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1089

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6121

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2983

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习