1. 简介
在此 Codelab 中,您将学习如何部署 AlloyDB Omni 并使用列式引擎来提升查询性能。
前提条件
- 对 Google Cloud 控制台有基本的了解
- 具备命令行界面和 Google Shell 方面的基本技能
学习内容
- 如何在 Google Cloud 的 GCE 虚拟机上部署 AlloyDB Omni
- 如何连接到 AlloyDB Omni
- 如何将数据加载到 AlloyDB Omni
- 如何启用列式引擎
- 如何在自动模式下检查列式引擎
- 如何手动填充列式存储区
所需条件
- Google Cloud 账号和 Google Cloud 项目
- 网络浏览器,例如 Chrome
2. 设置和要求
自定进度的环境设置
- 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。
- 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
- 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用
PROJECT_ID
标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。 - 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档。
- 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。
启动 Cloud Shell
虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。
在 Google Cloud 控制台 中,点击右上角工具栏中的 Cloud Shell 图标:
预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:
这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的所有工作都可以在浏览器中完成。您无需安装任何程序。
3. 准备工作
启用 API
输出如下:
在 Cloud Shell 中,确保项目 ID 已设置:
PROJECT_ID=$(gcloud config get-value project)
echo $PROJECT_ID
如果 Cloud Shell 配置中未定义该环境变量,请使用以下命令进行设置
export PROJECT_ID=<your project>
gcloud config set project $PROJECT_ID
启用所有必要的服务:
gcloud services enable compute.googleapis.com
预期输出
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-14650] student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417 Updated property [core/project]. student@cloudshell:~ (test-project-001-402417)$ gcloud services enable compute.googleapis.com Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
4. 在 GCE 上部署 AlloyDB Omni
如需在 GCE 上部署 AlloyDB Omni,我们需要准备具有兼容配置和软件的虚拟机。下面的示例展示了如何在基于 Debian 的虚拟机上部署 AlloyDB Omni。
创建 GCE 虚拟机
我们需要部署一个 CPU、内存和存储空间配置可接受的虚拟机。我们将使用将系统磁盘大小增加到 20 GB 的默认 Debian 映像,以容纳 AlloyDB Omni 数据库文件。
我们可以使用已启动的 Cloud Shell 或安装了 Cloud SDK 的终端
AlloyDB Omni 的快速入门 中也介绍了所有步骤。
为您的部署设置环境变量。
export ZONE=us-central1-a
export MACHINE_TYPE=n2-highmem-2
export DISK_SIZE=20
export MACHINE_NAME=omni01
然后,我们使用 gcloud 创建 GCE 虚拟机。
gcloud compute instances create $MACHINE_NAME \
--project=$(gcloud info --format='value(config.project)') \
--zone=$ZONE --machine-type=$MACHINE_TYPE \
--metadata=enable-os-login=true \
--create-disk=auto-delete=yes,boot=yes,size=$DISK_SIZE,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" \
--format="value(name)"),type=pd-ssd
预期的控制台输出:
gleb@cloudshell:~ (gleb-test-short-001-415614)$ export ZONE=us-central1-a export MACHINE_TYPE=n2-highmem-2 export DISK_SIZE=20 export MACHINE_NAME=omni01 gleb@cloudshell:~ (gleb-test-short-001-415614)$ gcloud compute instances create $MACHINE_NAME \ --project=$(gcloud info --format='value(config.project)') \ --zone=$ZONE --machine-type=$MACHINE_TYPE \ --metadata=enable-os-login=true \ --create-disk=auto-delete=yes,boot=yes,size=$DISK_SIZE,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" \ --format="value(name)"),type=pd-ssd Created [https://www.googleapis.com/compute/v1/projects/gleb-test-short-001-415614/zones/us-central1-a/instances/omni01]. WARNING: Some requests generated warnings: - Disk size: '20 GB' is larger than image size: '10 GB'. You might need to resize the root repartition manually if the operating system does not support automatic resizing. See https://cloud.google.com/compute/docs/disks/add-persistent-disk#resize_pd for details. NAME: omni01 ZONE: us-central1-a MACHINE_TYPE: n2-highmem-2 PREEMPTIBLE: INTERNAL_IP: 10.128.0.3 EXTERNAL_IP: 35.232.157.123 STATUS: RUNNING gleb@cloudshell:~ (gleb-test-short-001-415614)$
安装 AlloyDB Omni
连接到创建的虚拟机:
gcloud compute ssh omni01 --zone $ZONE
预期的控制台输出:
gleb@cloudshell:~ (gleb-test-short-001-415614)$ gcloud compute ssh omni01 --zone $ZONE Warning: Permanently added 'compute.5615760774496706107' (ECDSA) to the list of known hosts. Linux omni01.us-central1-a.c.gleb-test-short-003-421517.internal 6.1.0-20-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.85-1 (2024-04-11) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. gleb@omni01:~$
在已连接的终端中运行以下命令。
在虚拟机上安装 Docker:
sudo apt update
sudo apt-get -y install docker.io
预期的控制台输出(已隐去部分信息):
gleb@omni01:~$ sudo apt update sudo apt-get -y install docker.io Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [30 B] Get:5 file:/etc/apt/mirrors/debian-security.list Mirrorlist [39 B] Get:7 https://packages.cloud.google.com/apt google-compute-engine-bookworm-stable InRelease [5146 B] Get:8 https://packages.cloud.google.com/apt cloud-sdk-bookworm InRelease [6406 B] Get:9 https://packages.cloud.google.com/apt google-compute-engine-bookworm-stable/main amd64 Packages [1916 B] Get:2 https://deb.debian.org/debian bookworm InRelease [151 kB] ... Setting up binutils (2.40-2) ... Setting up needrestart (3.6-4+deb12u1) ... Processing triggers for man-db (2.11.2-2) ... Processing triggers for libc-bin (2.36-9+deb12u4) ... gleb@omni01:~$
为 postgres 用户定义密码:
export PGPASSWORD=<your password>
为 AlloyDB Omni 数据创建一个目录。这是一个可选方法,但我们建议您这样做。默认情况下,系统会使用 Docker 临时文件系统层创建数据,并在删除 Docker 容器时销毁所有内容。将其单独保留可让您独立于数据管理容器,并可选择将其放置到 IO 特性更佳的存储空间
以下命令会在用户的主目录中创建一个目录,用于存放所有数据:
mkdir -p $HOME/alloydb-data
部署 AlloyDB Omni 容器:
sudo docker run --name my-omni \
-e POSTGRES_PASSWORD=$PGPASSWORD \
-p 5432:5432 \
-v $HOME/alloydb-data:/var/lib/postgresql/data \
-v /dev/shm:/dev/shm \
-d google/alloydbomni
预期的控制台输出(已隐去部分信息):
gleb@omni01:~$ export PGPASSWORD=StrongPassword gleb@omni01:~$ sudo docker run --name my-omni \ -e POSTGRES_PASSWORD=$PGPASSWORD \ -p 5432:5432 \ -v $HOME/alloydb-data:/var/lib/postgresql/data \ -v /dev/shm:/dev/shm \ -d google/alloydbomni Unable to find image 'google/alloydbomni:latest' locally latest: Pulling from google/alloydbomni 71215d55680c: Pull complete ... 2e0ec3fe1804: Pull complete Digest: sha256:d6b155ea4c7363ef99bf45a9dc988ce5467df5ae8cd3c0f269ae9652dd1982a6 Status: Downloaded newer image for google/alloydbomni:latest 56de4ae0018314093c8b048f69a1e9efe67c6c8117f44c8e1dc829a2d4666cd2 gleb@omni01:~$
将 PostgreSQL 客户端软件安装到虚拟机(可选 - 预计已安装):
sudo apt install -y postgresql-client
预期的控制台输出:
gleb@omni01:~$ sudo apt install -y postgresql-client Reading package lists... Done Building dependency tree... Done Reading state information... Done postgresql-client is already the newest version (15+248). 0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
连接到 AlloyDB Omni:
psql -h localhost -U postgres
预期的控制台输出:
gleb@omni01:~$ psql -h localhost -U postgres psql (15.6 (Debian 15.6-0+deb12u1), server 15.5) Type "help" for help. postgres=#
断开与 AlloyDB Omni 的连接:
exit
预期的控制台输出:
postgres=# exit gleb@omni01:~$
5. 准备测试数据库
如需测试列式引擎,我们需要创建一个数据库并向其中填充一些测试数据。
创建数据库
连接到 AlloyDB Omni 虚拟机并创建数据库
在 Cloud Shell 会话中,执行以下命令:
gcloud config set project $(gcloud config get-value project)
连接到 AlloyDB Omni 虚拟机:
ZONE=us-central1-a
gcloud compute ssh omni01 --zone $ZONE
预期的控制台输出:
student@cloudshell:~ (gleb-test-short-001-416213)$ gcloud config set project $(gcloud config get-value project) Updated property [core/project]. student@cloudshell:~ (gleb-test-short-001-416213)$ ZONE=us-central1-a gcloud compute ssh omni01 --zone $ZONE Linux omni01.us-central1-a.c.gleb-test-short-003-421517.internal 6.1.0-20-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.85-1 (2024-04-11) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Mar 4 18:17:55 2024 from 35.237.87.44 student@omni01:~$
在建立的 SSH 会话中,执行以下命令:
export PGPASSWORD=<your password>
psql -h localhost -U postgres -c "CREATE DATABASE quickstart_db"
预期的控制台输出:
student@omni01:~$ psql -h localhost -U postgres -c "CREATE DATABASE quickstart_db" CREATE DATABASE student@omni01:~$
创建包含示例数据的表
在测试中,我们将使用有关爱荷华州持证保险业务员的公开数据。您可以在爱荷华州政府网站 https://data.iowa.gov/Regulation/Insurance-Producers-Licensed-in-Iowa/n4cc-vqyk/about_data 上找到此数据集。
首先,我们需要创建一个表。
在 GCE 虚拟机中,执行以下命令:
psql -h localhost -U postgres -d quickstart_db -c "DROP TABLE if exists insurance_producers_licensed_in_iowa;
CREATE TABLE insurance_producers_licensed_in_iowa (
npn int8,
last_name text,
first_name text,
address_line_1 text,
address_line_2 text,
address_line_3 text,
city text,
state text,
zip int4,
firstactivedate timestamp,
expirydate timestamp,
business_phone text,
email text,
physical_location text,
iowaresident text,
loa_has_crop text,
loa_has_surety text,
loa_has_ah text,
loa_has_life text,
loa_has_variable text,
loa_has_personal_lines text,
loa_has_credit text,
loa_has_excess text,
loa_has_property text,
loa_has_casualty text,
loa_has_reciprocal text
);"
预期的控制台输出:
otochkin@omni01:~$ psql -h localhost -U postgres -d quickstart_db -c "DROP TABLE if exists insurance_producers_licensed_in_iowa; CREATE TABLE insurance_producers_licensed_in_iowa ( npn int8, last_name text, first_name text, address_line_1 text, address_line_2 text, address_line_3 text, city text, state text, zip int4, firstactivedate timestamp, expirydate timestamp, business_phone text, email text, physical_location text, iowaresident text, loa_has_crop text, loa_has_surety text, loa_has_ah text, loa_has_life text, loa_has_variable text, loa_has_personal_lines text, loa_has_credit text, loa_has_excess text, loa_has_property text, loa_has_casualty text, loa_has_reciprocal text );" NOTICE: table "insurance_producers_licensed_in_iowa" does not exist, skipping DROP TABLE CREATE TABLE otochkin@omni01:~$
将数据加载到表中。
在 GCE 虚拟机中,执行以下命令:
curl https://data.iowa.gov/api/views/n4cc-vqyk/rows.csv | psql -h localhost -U postgres -d quickstart_db -c "\copy insurance_producers_licensed_in_iowa from stdin csv header"
预期的控制台输出:
otochkin@omni01:~$ curl https://data.iowa.gov/api/views/n4cc-vqyk/rows.csv | psql -h localhost -U postgres -d quickstart_db -c "\copy insurance_producers_licensed_in_iowa from stdin csv header" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 39.3M 0 39.3M 0 0 1004k 0 --:--:-- 0:00:40 --:--:-- 1028k COPY 210898 otochkin@omni01:~$
我们已将 210898 条与保险生产商有关的记录加载到数据库中,现在可以进行一些测试了。
运行测试查询
使用 psql 连接到 quickstart_db,并启用计时功能以衡量查询的执行时间。
在 GCE 虚拟机中,执行以下命令:
psql -h localhost -U postgres -d quickstart_db
预期的控制台输出:
student@omni01:~$ psql -h localhost -U postgres -d quickstart_db psql (13.14 (Debian 13.14-0+deb11u1), server 15.5 WARNING: psql major version 13, server major version 15. Some psql features might not work. Type "help" for help. quickstart_db=#
在 PSQL 会话中,执行以下命令:
\timing
预期的控制台输出:
quickstart_db=# \timing Timing is on. quickstart_db=#
我们来按销售意外伤害保险和健康保险且其执照至少在未来 6 个月内有效的保险代理数量,找出前 5 个城市。
在 PSQL 会话中,执行以下命令:
SELECT city, count(*)
FROM insurance_producers_licensed_in_iowa
WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH'
GROUP BY city ORDER BY count(*) desc limit 5;
预期的控制台输出:
quickstart_db=# SELECT city, count(*) FROM insurance_producers_licensed_in_iowa WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH' GROUP BY city ORDER BY count(*) desc limit 5; city | count -------------+------- TAMPA | 1885 OMAHA | 1656 KANSAS CITY | 1279 AUSTIN | 1254 MIAMI | 1003 (5 rows) Time: 94.965 ms
最好多次运行测试查询,以获取可靠的执行时间。我们可以看到,返回结果的平均时间约为 94 毫秒。在后续步骤中,我们将启用 AlloyDB 列式引擎,看看它能否提升性能。
退出 psql 会话:
exit
6. 启用列式引擎
现在,我们需要在 AlloyDB Omni 上启用列式引擎。
更新 AlloyDB Omni 参数
我们需要将 AlloyDB Omni 的实例参数“google_columnar_engine.enabled”切换为“on”,并且需要重启。
更新 /var/alloydb/config 目录中的 postgresql.conf,然后重启实例。
在 GCE 虚拟机中,执行以下命令:
sudo docker exec my-omni /bin/bash -c "echo google_columnar_engine.enabled=true >>/var/lib/postgresql/data/postgresql.conf"
sudo docker exec my-omni /bin/bash -c "echo shared_preload_libraries=\'google_columnar_engine,google_job_scheduler,google_db_advisor,google_storage\' >>/var/lib/postgresql/data/postgresql.conf"
sudo docker stop my-omni
sudo docker start my-omni
预期的控制台输出:
student@omni01:~$ sudo docker exec my-omni /bin/bash -c "echo google_columnar_engine.enabled=true >>/var/lib/postgresql/data/postgresql.conf" sudo docker exec my-omni /bin/bash -c "echo shared_preload_libraries=\'google_columnar_engine,google_job_scheduler,google_db_advisor,google_storage\' >>/var/lib/postgresql/data/postgresql.conf" sudo docker stop my-omni sudo docker start my-omni my-omni my-omni student@omni01:~$
验证列式引擎
使用 psql 连接到数据库,并验证列式引擎。
连接到 AlloyDB Omni 数据库
在虚拟机 SSH 会话中,连接到数据库:
psql -h localhost -U postgres -d quickstart_db -c "show google_columnar_engine.enabled"
该命令应显示已启用的列式引擎。
预期的控制台输出:
student@omni01:~$ psql -h localhost -U postgres -d quickstart_db -c "show google_columnar_engine.enabled" google_columnar_engine.enabled -------------------------------- on (1 row)
7. 效果对比
现在,我们可以填充列式引擎存储区并验证性能。
自动列式存储区填充
默认情况下,用于填充商店的作业每小时运行一次。我们将把此时间缩短至 10 分钟,以免您需要等待。
在 GCE 虚拟机中,执行以下命令:
sudo docker exec my-omni /bin/bash -c "echo google_columnar_engine.auto_columnarization_schedule=\'EVERY 10 MINUTES\' >>/var/lib/postgresql/data/postgresql.conf"
sudo docker stop my-omni
sudo docker start my-omni
预期输出如下:
student@omni01:~$ sudo docker exec my-omni /bin/bash -c "echo google_columnar_engine.auto_columnarization_schedule=\'EVERY 5 MINUTES\' >>/var/lib/postgresql/data/postgresql.conf" sudo docker stop my-omni sudo docker start my-omni my-omni my-omni student@omni01:~$
验证设置
在 GCE 虚拟机中,执行以下命令:
psql -h localhost -U postgres -d quickstart_db -c "show google_columnar_engine.auto_columnarization_schedule;"
预期输出:
student@omni01:~$ psql -h localhost -U postgres -d quickstart_db -c "show google_columnar_engine.auto_columnarization_schedule;" google_columnar_engine.auto_columnarization_schedule ------------------------------------------------------ EVERY 10 MINUTES (1 row) student@omni01:~$
检查列存储区中的对象。它应该为空。
在 GCE 虚拟机中,执行以下命令:
psql -h localhost -U postgres -d quickstart_db -c "SELECT database_name, schema_name, relation_name, column_name FROM g_columnar_recommended_columns;"
预期输出:
student@omni01:~$ psql -h localhost -U postgres -d quickstart_db -c "SELECT database_name, schema_name, relation_name, column_name FROM g_columnar_recommended_columns;" database_name | schema_name | relation_name | column_name ---------------+-------------+---------------+------------- (0 rows) student@omni01:~$
连接到数据库,然后多次运行我们之前执行的相同查询。
在 GCE 虚拟机中,执行以下命令:
psql -h localhost -U postgres -d quickstart_db
在 PSQL 会话中。
启用计时功能
\timing
多次运行该查询:
SELECT city, count(*)
FROM insurance_producers_licensed_in_iowa
WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH'
GROUP BY city ORDER BY count(*) desc limit 5;
预期输出:
quickstart_db=# SELECT city, count(*) FROM insurance_producers_licensed_in_iowa WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH' GROUP BY city ORDER BY count(*) desc limit 5; city | count -------------+------- TAMPA | 1885 OMAHA | 1656 KANSAS CITY | 1279 AUSTIN | 1254 MIAMI | 1003 (5 rows) Time: 94.289 ms quickstart_db=# SELECT city, count(*) FROM insurance_producers_licensed_in_iowa WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH' GROUP BY city ORDER BY count(*) desc limit 5; city | count -------------+------- TAMPA | 1885 OMAHA | 1656 KANSAS CITY | 1279 AUSTIN | 1254 MIAMI | 1003 (5 rows) Time: 94.608 ms quickstart_db=#
等待 10 分钟,然后检查 insurance_producers_licensed_in_iowa 表的列是否已填充到列存储区中。
SELECT database_name, schema_name, relation_name, column_name FROM g_columnar_recommended_columns;
预期输出:
quickstart_db=# SELECT database_name, schema_name, relation_name, column_name FROM g_columnar_recommended_columns; database_name | schema_name | relation_name | column_name ---------------+-------------+--------------------------------------+------------- quickstart_db | public | insurance_producers_licensed_in_iowa | city quickstart_db | public | insurance_producers_licensed_in_iowa | expirydate quickstart_db | public | insurance_producers_licensed_in_iowa | loa_has_ah (3 rows) Time: 0.643 ms
现在,我们可以再次针对 insurance_producers_licensed_in_iowa 表运行查询,看看性能是否有所提升。
SELECT city, count(*)
FROM insurance_producers_licensed_in_iowa
WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH'
GROUP BY city ORDER BY count(*) desc limit 5;
预期输出:
quickstart_db=# SELECT city, count(*) FROM insurance_producers_licensed_in_iowa WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH' GROUP BY city ORDER BY count(*) desc limit 5; city | count -------------+------- TAMPA | 1885 OMAHA | 1656 KANSAS CITY | 1279 AUSTIN | 1254 MIAMI | 1003 (5 rows) Time: 14.380 ms quickstart_db=# SELECT city, count(*) FROM insurance_producers_licensed_in_iowa WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH' GROUP BY city ORDER BY count(*) desc limit 5; city | count -------------+------- TAMPA | 1885 OMAHA | 1656 KANSAS CITY | 1279 AUSTIN | 1254 MIAMI | 1003 (5 rows) Time: 13.279 ms
执行时间从 94 毫秒缩短到了 14 毫秒。如果您没有看到任何改进,可以通过查看 g_columnar_columns 视图,检查列是否已成功填充到列存储区。
SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns;
预期输出:
quickstart_db=# select relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns; relation_name | column_name | column_type | status | size_in_bytes --------------------------------------+-------------+-------------+--------+--------------- insurance_producers_licensed_in_iowa | city | text | Usable | 664231 insurance_producers_licensed_in_iowa | expirydate | timestamp | Usable | 212434 insurance_producers_licensed_in_iowa | loa_has_ah | text | Usable | 211734 (3 rows)
现在,我们可以验证查询执行计划是否使用了列式引擎。
在 PSQL 会话中,执行以下命令:
EXPLAIN (ANALYZE,SETTINGS,BUFFERS)
SELECT city, count(*)
FROM insurance_producers_licensed_in_iowa
WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH'
GROUP BY city ORDER BY count(*) desc limit 5;
预期输出:
quickstart_db=# EXPLAIN (ANALYZE,SETTINGS,BUFFERS) SELECT city, count(*) FROM insurance_producers_licensed_in_iowa WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH' GROUP BY city ORDER BY count(*) desc limit 5; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=2279.72..2279.73 rows=5 width=17) (actual time=12.248..12.252 rows=5 loops=1) -> Sort (cost=2279.72..2292.91 rows=5277 width=17) (actual time=12.246..12.248 rows=5 loops=1) Sort Key: (count(*)) DESC Sort Method: top-N heapsort Memory: 25kB -> HashAggregate (cost=2139.30..2192.07 rows=5277 width=17) (actual time=10.235..11.250 rows=7555 loops=1) Group Key: city Batches: 1 Memory Usage: 1169kB -> Append (cost=20.00..1669.24 rows=94012 width=9) (actual time=10.231..10.233 rows=94286 loops=1) -> Custom Scan (columnar scan) on insurance_producers_licensed_in_iowa (cost=20.00..1665.22 rows=94011 width=9) (actual time=10.229..10.231 rows=94286 loops=1) Filter: ((loa_has_ah = 'Yes'::text) AND (expirydate > (now() + '6 mons'::interval))) Rows Removed by Columnar Filter: 116612 Rows Aggregated by Columnar Scan: 94286 Columnar cache search mode: native -> Seq Scan on insurance_producers_licensed_in_iowa (cost=0.00..4.02 rows=1 width=9) (never executed) Filter: ((loa_has_ah = 'Yes'::text) AND (expirydate > (now() + '6 mons'::interval))) Planning Time: 0.216 ms Execution Time: 12.353 ms
我们可以看到,系统从未对 business_licenses 表分块执行“Seq Scan”操作,而是改用“Custom Scan(列式扫描)”。这有助于我们将响应时间从 94 毫秒缩短到 12 毫秒。
如果我们想从列式引擎中清除自动填充的内容,可以使用 SQL 函数 google_columnar_engine_reset_recommendation 来实现。
在 PSQL 会话中,执行以下命令:
SELECT google_columnar_engine_reset_recommendation(drop_columns => true);
这会清除已填充的列,您可以在视图 g_columnar_columns 和 g_columnar_recommended_columns 中进行验证,如前所示。
SELECT database_name, schema_name, relation_name, column_name FROM g_columnar_recommended_columns;
SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns;
预期输出:
quickstart_db=# SELECT database_name, schema_name, relation_name, column_name FROM g_columnar_recommended_columns; database_name | schema_name | relation_name | column_name ---------------+-------------+---------------+------------- (0 rows) Time: 0.447 ms quickstart_db=# select relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns; relation_name | column_name | column_type | status | size_in_bytes ---------------+-------------+-------------+--------+--------------- (0 rows) Time: 0.556 ms quickstart_db=#
手动填充列式存储区
我们可以使用 SQL 函数手动向列式引擎存储区添加列,也可以在实例标志中指定所需的实体,以便在实例启动时自动加载这些实体。
我们使用 google_columnar_engine_add SQL 函数添加与之前相同的列。
在 PSQL 会话中,执行以下命令:
SELECT google_columnar_engine_add(relation => 'insurance_producers_licensed_in_iowa', columns => 'city,expirydate,loa_has_ah');
我们可以使用相同的 g_columnar_columns 视图验证结果:
SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns;
预期输出:
quickstart_db=# SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns; relation_name | column_name | column_type | status | size_in_bytes --------------------------------------+-------------+-------------+--------+--------------- insurance_producers_licensed_in_iowa | city | text | Usable | 664231 insurance_producers_licensed_in_iowa | expirydate | timestamp | Usable | 212434 insurance_producers_licensed_in_iowa | loa_has_ah | text | Usable | 211734 (3 rows) Time: 0.692 ms quickstart_db=#
您可以通过运行与之前相同的查询并检查执行计划,验证是否使用了列式存储:
EXPLAIN (ANALYZE,SETTINGS,BUFFERS)
SELECT city, count(*)
FROM insurance_producers_licensed_in_iowa
WHERE loa_has_ah ='Yes' and expirydate > now() + interval '6 MONTH'
GROUP BY city ORDER BY count(*) desc limit 5;
退出 psql 会话:
exit
如果我们重启 AlloyDB Omni 容器,就会发现所有列信息都丢失了。
在 shell 会话中,执行以下命令:
sudo docker stop my-omni
sudo docker start my-omni
等待 5-10 秒钟,然后运行以下命令:
psql -h localhost -U postgres -d quickstart_db -c "SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns"
预期输出:
student@omni01:~$ psql -h localhost -U postgres -d quickstart_db -c "SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns" relation_name | column_name | column_type | status | size_in_bytes ---------------+-------------+-------------+--------+--------------- (0 rows)
如需在重启期间自动重新填充这些列,我们可以将它们作为数据库标志添加到 AlloyDB Omni 参数中。我们将添加标志 google_columnar_engine.relations=‘quickstart_db.public.insurance_producers_licensed_in_iowa(city,expirydate,loa_has_ah)' 并重启容器。
在 shell 会话中,执行以下命令:
sudo docker exec my-omni /bin/bash -c "echo google_columnar_engine.relations=\'quickstart_db.public.insurance_producers_licensed_in_iowa\(city,expirydate,loa_has_ah\)\' >>/var/lib/postgresql/data/postgresql.conf"
sudo docker stop my-omni
sudo docker start my-omni
之后,我们可以看到这些列在启动后已自动添加到列存储区。
等待 5-10 秒钟,然后运行以下命令:
psql -h localhost -U postgres -d quickstart_db -c "SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns"
预期输出:
student@omni01:~$ psql -h localhost -U postgres -d quickstart_db -c "SELECT relation_name,column_name,column_type,status,size_in_bytes from g_columnar_columns" relation_name | column_name | column_type | status | size_in_bytes --------------------------------------+-------------+-------------+--------+--------------- insurance_producers_licensed_in_iowa | city | text | Usable | 664231 insurance_producers_licensed_in_iowa | expirydate | timestamp | Usable | 212434 insurance_producers_licensed_in_iowa | loa_has_ah | text | Usable | 211734 (3 rows)
8. 清理环境
现在,我们可以销毁 AlloyDB Omni 虚拟机了
删除 GCE 虚拟机
在 Cloud Shell 中,执行以下命令:
export GCEVM=omni01
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
--zone=$ZONE \
--quiet
预期的控制台输出:
student@cloudshell:~ (test-project-001-402417)$ export GCEVM=omni01 export ZONE=us-central1-a gcloud compute instances delete $GCEVM \ --zone=$ZONE \ --quiet Deleted
9. 恭喜
恭喜您完成此 Codelab。
所学内容
- 如何在 Google Cloud 的 GCE 虚拟机上部署 AlloyDB Omni
- 如何连接到 AlloyDB Omni
- 如何将数据加载到 AlloyDB Omni
- 如何启用列式引擎
- 如何在自动模式下检查列式引擎
- 如何手动填充列式存储
如需详细了解如何使用列式引擎,请参阅文档。
10. 调查问卷
输出如下: