表达式虚拟列可加快列式引擎查询的速度,这些查询会重复评估相同的表达式,例如对 JSON 属性的过滤条件。此功能适用于 PostgreSQL 16 及更高版本。
列式引擎可以具体化并缓存常用表达式的结果。通过预先计算并存储这些结果,AlloyDB 可避免在多个查询中重复解析和评估相同的表达式。此过程可提高查询性能并减少 CPU 消耗,尤其适用于大型数据集上的分析工作负载。
表达式虚拟列的一些应用场景如下:
- 过滤 JSON 属性:当您经常根据 JSON 列中的特定键值对过滤查询时。
- 复杂表达式求值:适用于涉及复杂或计算密集型表达式的查询。
启用表达式扫描的虚拟列后,使用列式引擎且包含常用表达式的查询会自动优化。列式引擎在刷新基列时会自动刷新这些虚拟列。
虚拟列中支持的表达式
AlloyDB 在(预览版)中支持对 JSON 和 JSONB 列使用 -> 和 ->> 运算符。
准备工作
为 AlloyDB 集群启用列式引擎。如需了解详情,请参阅配置列式引擎。
使用 Query Insights 识别 AlloyDB 查询中常用的表达式。
将表达式的基础列添加到列式引擎。如需了解详情,请参阅手动管理列存储区内容。
为表达式启用虚拟列
默认情况下,系统会启用对表达式虚拟列的支持 (google_columnar_engine.enable_virtual_columns_scan=on)。如果此标志之前处于停用状态,您可以使用 gcloud alloydb instances update 命令为实例启用此标志。
如需使用 gcloud CLI,您可以安装并初始化 Google Cloud CLI,也可以使用 Cloud Shell。
gcloud alloydb instances update INSTANCE_ID \
--region=REGION_ID \
--cluster=CLUSTER_ID \
--project=PROJECT_ID \
--database-flags="google_columnar_engine.enable_virtual_columns_scan=on"替换以下内容:
INSTANCE_ID:您的 AlloyDB 实例 ID。REGION_ID:AlloyDB 实例的区域。CLUSTER_ID:AlloyDB 实例的集群 ID。PROJECT_ID:您的 Google Cloud 项目 ID。
如需在会话级设置此标志,请运行以下命令:
SET google_columnar_engine.enable_virtual_columns_scan=on;
为表达式添加虚拟列
如需将常用表达式添加到列式引擎,请使用 psql 客户端调用 google_columnar_engine_add 函数。除了数据库中已有的列之外,这些表达式还会作为列填充到列式引擎中。
您可以指定多个表达式,以逗号分隔值。
SELECT google_columnar_engine_add(
relation => 'DB.SCHEMA.TABLE_NAME',
columns => 'COLUMN_NAME, COLUMN_NAME',
expressions => 'EXP1, EXP2, EXP3'
);
替换以下内容:
DB.SCHEMA:存储表的数据库架构。TABLE_NAME:存储列的表的名称。COLUMN_NAME:包含表达式的列的名称。EXP1, EXP2, EXP3:逗号分隔列表中的表达式。支持的 JSON 提取表达式为->和->>。例如,如需为
public架构中的employee表添加user ->> 'email'和user ->> 'name'表达式,请使用以下查询:SELECT google_columnar_engine_add( relation => 'postgres.public.employee', expressions => '"user ->> ''email''", "user ->> ''name''"' );表达式语法:
- 用英文单引号将整个表达式值括起来,例如
expressions => 'EXP1,EXP2,EXP3'。 - 使用英文逗号分隔多个表达式。
- 请用双引号将每个表达式括起来。
- 使用另一个单引号对表达式中的任何单引号进行转义。
例如,如需添加
col -> 'level1'和col -> 'level1' ->> 'level2'表达式,请使用以下格式:expressions => '"col -> ''level1''", "col -> ''level1'' ->> ''level2''"'- 用英文单引号将整个表达式值括起来,例如
表达式虚拟列示例
此示例演示了如何使用表达式虚拟列功能。创建一个包含 profile JSONB 列的 users 表,并使用示例数据填充该表。然后,根据查询分析,使用 google_columnar_engine_add 函数将常用的 profile ->> 'email' 表达式添加到列式引擎。然后,列式引擎会使用此频繁表达式来帮助优化后续查询。
如需将此示例频繁表达式添加到列式引擎,请按照以下步骤操作:
在 Google Cloud 控制台中,前往集群页面。
在资源名称列中,点击集群的名称。
在导航窗格中,点击 AlloyDB Studio。
如需创建包含
profileJSONB 列的users表,请运行以下命令:CREATE TABLE users ( id int, username TEXT, profile JSONB );如需使用示例数据填充
users表,请运行以下命令:INSERT INTO users (id, username, profile) SELECT i, 'user' || i, jsonb_build_object( 'name', 'User ' || i, 'email', 'user' || i || '@example.com', 'active', (i % 2 = 0) ) FROM generate_series(1, 100000) AS i;如需提升包含常用表达式的查询的性能,请将
profile ->> 'email'表达式添加到列式引擎:SELECT google_columnar_engine_add( relation => 'users', columns => 'username, profile', expressions => '"profile ->> ''email''"' );停用表达式虚拟列功能以建立性能基准,然后运行使用频繁表达式的查询,并观察查询完成所需的时间。
SET google_columnar_engine.enable_virtual_columns_scan=off; SELECT username FROM users WHERE profile->>'email' = 'user50000@example.com';启用表达式虚拟列功能。
SET google_columnar_engine.enable_virtual_columns_scan=on;重新运行使用频繁表达式的查询,并观察查询完成所需的时间。
SELECT username FROM users WHERE profile->>'email' = 'user50000@example.com';
为表达式启用虚拟列后,查询运行时会更快。
查看表达式的虚拟列
如需查找为特定表添加的所有表达式,请查询 g_columnar_virtual_columns 视图:
SELECT * FROM g_columnar_virtual_columns;
输出类似于以下内容,其中 description 字段显示为表(关系)添加的所有表达式:
category | expression
database_name | testdb
schemas | {public}
relations | {users}
description | profile->>'email'
column_data_type | text
status | Usable
last_accessed_time | 2026-02-04 06:25:32.499601+00
num_times_accessed | 1
移除表达式的虚拟列
如需移除表达式,请调用 google_columnar_engine_drop() 函数:
SELECT google_columnar_engine_drop(
relation => 'DB.SCHEMA.TABLE_NAME',
expressions => 'EXP1, EXP2, EXP3'
);
将 EXP1, EXP2, EXP3 替换为表中以英文逗号分隔的表达式列表,格式与添加表达式时使用的格式相同。