什么是谓词下推?
谓词下推是一种查询优化:它在语义合法且技术可行的前提下,把过滤条件放到尽可能靠近数据扫描或数据源的位置执行。引擎不必传输所有候选行后再过滤,而可以在扫描算子、列式读取器、连接器生成的远端查询或存储服务中执行全部或部分WHERE条件或连接条件。
谓词是在SQL三值逻辑下求值为真、假或未知的表达式。下推改变的是表达式的求值位置,而不是含义。优化器必须证明:把条件跨越连接、聚合、窗口、类型转换或数据源边界移动后,行、重复项与NULL行为仍然一致。
快速判断:如果计划或远端查询显示过滤在扫描端或源端执行,并且行数或字节在跨越下一边界前减少,通常说明发生了下推。仍需用源端遥测与结果等价测试确认;仅凭SQL文本不能证明。
谓词下推如何穿过查询计划
- 解析谓词。
引擎绑定名称与类型,在支持时展开视图,并在逻辑计划中表示条件。语法合法并不保证可以下推。
- 证明移动合法。
重写规则判断谓词能否在不改变语义的情况下跨越投影、连接、聚合或其他算子。有时只有一个合取项可以移动。
- 询问扫描器或连接器支持范围。
文件读取器可能只接受有限比较;连接器可能把表达式翻译为远端方言。能力会因类型、操作符、函数与版本而变化。
- 拆分已接受与残余过滤。
数据源执行已接受约束;当源端返回安全超集、只处理部分条件或无法保证语义一致时,引擎保留残余过滤。
- 估算并执行新计划。
优化器利用估算选择率、扫描、传输与源端成本比较合法位置。实际减少量可能偏离估算,因此仍需测量。
谓词下推与分区裁剪、投影下推有什么区别?
| 机制 | 减少内容 | 输入 | 不能证明 |
|---|---|---|---|
| 谓词下推 | 扫描/源端以上的行 | 符合条件的行表达式 | 物理块一定被跳过 |
| 分区裁剪 | 打开的分区或分区文件 | 分区键条件 | 保留分区内部过滤 |
| 数据跳过 | 读取的文件、行组或页面 | 最小/最大值、字典、索引或布隆元数据 | 保留的每行都匹配 |
| 投影下推 | 列与列字节 | 必需列清单 | 行数减少 |
| 动态过滤 | 运行时值已知后的探测数据 | 从另一输入得到的值 | 编译期静态谓词 |
这些机制可以叠加:日期条件裁剪分区,行组统计跳过数据块,投影下推避免读取无用列,残余过滤再删除保留行组中的不匹配行。应分别报告每种效果。
过滤位置必须服从语义安全
只有移动后的表达式产生等价行多重集时,下推才合法。SQL的NULL与重复项语义会让看似显然的重写变得危险;源端翻译还会增加风险,因为不同系统比较字符串、时间戳、小数或无效值的方式可能不同。
如果错误移动空值补充端的条件,外连接可能变成内连接。ON与WHERE中的条件不能随意互换。
随机、依赖时钟、序列、用户上下文或易变函数,在更早、次数更少或其他位置执行时可能产生不同结果。
转换顺序、溢出、舍入与格式错误值的处理可能不同。下推转换可能触发原计划不会遇到的错误。
大小写敏感性、重音排序、尾随空格与时间戳边界必须一致。Trino提醒:大小写不敏感的源端不能精确执行大小写敏感约束。
为什么谓词下推没有发生?
过滤留在扫描上方,可能是移动不合法、实现缺少翻译、连接器拒绝表达式,或其他位置估算成本更低。重写SQL前,应先判断类别。
- 表达式形态:函数或转换包裹源列,或不受支持的操作符、相关子查询、复杂析取阻止翻译。
- 算子边界:聚合、窗口、限制、集合操作或外连接改变了谓词可见的行。
- 源端不匹配:类型、排序规则、时区、小数精度、NULL或函数语义不同。
- 能力与权限:连接器不支持、远端语法无法表达,或函数不允许调用。
- 延迟值:某些产品中的参数或变量可能阻止编译期约束。
- 成本:估算选择性较弱,或源端/网络成本支持本地执行时,合法下推也可能不采用。
谓词下推SQL示例
考虑下面的假设查询。名称与数字仅用于说明,不代表客户或基准测试。
SELECT o.order_id, c.segment
FROM remote_orders o
JOIN customers c ON c.customer_id = o.customer_id
WHERE o.order_date >= DATE '2026-07-01'
AND o.status = 'OPEN';如果连接器没有下推,远端扫描可能把所有订单返回协调器,再执行两个条件。安全下推后,连接器可以生成包含日期与状态约束的远端请求,使只有符合条件的行在本地连接前跨越网络。本地残余过滤仍可能保留作为安全检查。
示例测量:假设一次测试无下推时读取1200万源端行并传输800万行,下推后传输18万行。这只能支持“该样本传输减少”,不能证明源端页更少、源端CPU更低或其他参数也更快;这些指标必须分别测量。
如何逐步验证谓词下推
- 固定基线。
记录查询、版本、参数、缓存状态、并发与源端负载,并在变更前保存结果与计划。
- 定位过滤与边界。
标记扫描谓词、连接条件、残余过滤、数据交换、连接器与远端算子,并确定最早合法位置。
- 检查已委派表达式。
读取扫描属性、下推字段、远端SQL或API参数,并核对类型、转换与字面值边界。
- 测量边界两侧。
比较扫描/返回行与字节、传输、打开的文件或行组、源端CPU/I/O、协调器工作、延迟与波动。
- 证明结果等价。
在典型与对抗样本上比较计数、键、重复项、NULL与汇总。结果错误时,再快也不合格。
- 测试一个可逆变更。
每次只修改一个受支持的表达式、连接器选项、布局或访问路径。保留回滚并重跑证据集。
在引擎原生下推测试前审查过滤结构
请准备经过脱敏的完整SQL,并确认方言。InfiniSynapse SQL Complexity Checker会在浏览器中静态分析嵌套查询、CTE、连接、窗口、聚合与方言特定结构,可帮助定位复杂查询块中的过滤并安排计划检查优先级。
该检查器不会执行SQL,不会检查Schema、分区、行组元数据、连接器、生成的远端SQL或计划,不能证明下推,也不能预测节省的字节。完成结构审查后,应收集引擎原生证据。本地InfiniSynapse SQL查询优化指南解释更广泛流程;基于成本的优化器指南与数据联邦指南提供相关背景,但不声称这些本地文件已部署。
谓词下推常见问题
什么是谓词下推?
谓词下推是一种查询优化,会把符合条件的过滤表达式放到更靠近表扫描、列式文件读取器、连接器或远端数据源的位置执行。目标是减少流向后续算子的行或字节,但移动必须保持SQL语义。
谓词下推如何工作?
优化器先证明过滤可以合法向下移动,再询问扫描器或连接器支持哪些表达式,委派已接受部分,保留任何必要的残余谓词,并估算新计划的成本。具体行为因引擎、数据源、格式与版本而异。
谓词下推与分区裁剪相同吗?
不同。谓词下推改变行过滤条件的执行位置;分区裁剪利用分区元数据避免打开某些分区。一个条件可能同时启用两者,但计划与指标应分别报告它们的效果。
谓词下推与投影下推有什么区别?
谓词下推旨在减少行数;投影下推旨在避免读取或传输不需要的列。两者经常同时工作,但证明其中一个并不能证明另一个。
为什么过滤条件不能下推?
常见阻碍包括外连接或聚合语义、易变函数、类型转换、不受支持的操作符、排序规则或时区差异、连接器限制、延迟绑定值、权限,以及优化器估算本地执行成本更低。
谓词下推会改变查询结果吗?
正确下推不得改变结果。不安全的人工重写或错误翻译可能改变NULL保留、重复项、大小写比较、时间戳边界、舍入或错误行为。应使用典型与边界数据测试结果等价性。
如何在EXPLAIN中验证谓词下推?
检查过滤是否位于扫描或远端算子、已下推属性、生成的远端SQL,以及是否存在残余过滤;再确认边界前后的行和字节、源端工作、网络传输与结果等价。仅有计划标记还不够。
InfiniSynapse SQL Complexity Checker能证明谓词下推吗?
不能。其可见功能只在浏览器中静态分析SQL结构,不执行SQL,也不检查Schema、连接器、文件元数据、生成的远端请求或执行计划。可用它安排结构审查优先级,随后仍需进行引擎原生验证。
