Skip to main content
假设 PROJECTION 是虚拟的、作用域限于会话的 PROJECTION,你可以将其附加到 MergeTree 家族表上,而无需实际构建或存储它们。它们仅存在于当前会话中,可通过 EXPLAIN WHATIF 列出。 EXPLAIN WHATIF 会对普通 (排序) 假设 PROJECTION 进行估算:对于某个查询,读取该 PROJECTION 会涉及多少标记和行,以及优化器是否会选择它而不是基表。并非所有 PROJECTION 都会被估算:聚合 PROJECTION 和带有 WHERE 子句的 PROJECTION 就属于这种情况,未被估算的候选 PROJECTION 在列出时会附带原因。完整列表请参阅 EXPLAIN WHATIF。当前会话中的假设 PROJECTION 也可以在 system.hypothetical_projections 中查看。

CREATE HYPOTHETICAL PROJECTION

其语法与 ALTER TABLE ... ADD PROJECTION 相同,定义的校验方式也完全一致,因此在这里被拒绝的 PROJECTION 同样不可能被 materialized。此过程不会构建或写入任何内容——仅在当前会话中存储该描述。
  • name — PROJECTION 名称;在本会话中必须在 (database, table) 范围内唯一,且不得与表上已有的真实 PROJECTION 重名。
  • body 支持与真实 PROJECTION 相同的各种形式:使用 ORDER BY 的重排序 PROJECTION、使用 GROUP BY 的聚合 PROJECTION、使用 WHERE 的过滤 PROJECTION,或 PROJECTION 索引形式 INDEX <expression> TYPE <projection_index_type>。
  • WITH SETTINGS (...) 会被接受并保留;这些设置可在 system.hypothetical_projections 中查看。
目标表必须是位于 Atomic 数据库中的 MergeTree 家族表 (即必须具有 UUID) ,因为会话存储以表的 UUID 作为 entries 的键。真实 ADD PROJECTION 施加的各项限制在这里同样适用:带有 UNIQUE KEY 的表、在 deduplicate_merge_projection_mode = throw 下非 Ordinary 的 merging 模式、旧语法的 MergeTree 以及不可变磁盘均会被拒绝。 示例

DROP HYPOTHETICAL PROJECTION

从当前会话中移除一个假设投影。

DROP ALL HYPOTHETICAL PROJECTIONS

清除当前会话中定义的所有假设投影,不限表。该操作不会影响假设索引;DROP ALL HYPOTHETICAL INDEXES 的作用则相反。

作用域与生命周期

  • 假设投影仅存在于当前会话中——对其他会话不可见,并在会话结束时被丢弃。
  • 定义或删除假设投影不会真正构建 PROJECTION,也绝不会影响针对该表的普通查询。
  • 可通过 system.hypothetical_projections 查看当前会话的假设投影。

所需特权

CREATE HYPOTHETICAL PROJECTION 需要该表上的 ALTER ADD PROJECTION 特权——与真实的 ALTER TABLE ... ADD PROJECTION 所需特权相同——因为它会根据表的列校验该定义。EXPLAIN WHATIF 需要 PROJECTION 所涉及列上的列级 SELECT 特权才能对其进行估算,这与它对 CREATE HYPOTHETICAL INDEX 的现有要求一致。 DROP HYPOTHETICAL PROJECTION 需要相同的特权,从而确保在删除语句中指定某个表时,不会泄露该表是否存在或是否符合条件;此外,EXPLAIN WHATIF 在根据表校验已存储的定义之前,也会重新检查该特权。DROP ALL HYPOTHETICAL PROJECTIONS 不指定任何表,因此无需任何特权。

另请参阅