AlloyDB Omni에서 열 기반 엔진을 사용하여 분석 쿼리 가속화

1. 소개

이 Codelab에서는 AlloyDB Omni를 배포하고 Columnar Engine을 사용하여 쿼리 성능을 개선하는 방법을 알아봅니다.

7da257ba067ed1b1.png

기본 요건

  • Google Cloud 콘솔에 관한 기본적인 이해
  • 명령줄 인터페이스 및 Google 셸의 기본 기술

학습할 내용

  • Google Cloud의 GCE VM에 AlloyDB Omni를 배포하는 방법
  • AlloyDB Omni에 연결하는 방법
  • AlloyDB Omni에 데이터를 로드하는 방법
  • 열 기반 엔진을 사용 설정하는 방법
  • 자동 모드에서 열 엔진을 확인하는 방법
  • 열 형식 스토어를 수동으로 채우는 방법

필요한 항목

  • Google Cloud 계정 및 Google Cloud 프로젝트
  • 웹브라우저(예: Chrome)

2. 설정 및 요구사항

자습형 환경 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.

Cloud Shell 시작

Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.

Google Cloud Console의 오른쪽 상단 툴바에 있는 Cloud Shell 아이콘을 클릭합니다.

55efc1aaa7a4d3ad.png

환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 완료되면 다음과 같이 표시됩니다.

7ffe5cbb04455448.png

가상 머신에는 필요한 개발 도구가 모두 들어있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 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 기반 VM에 AlloyDB Omni를 배포하는 방법의 예입니다.

GCE VM 만들기

CPU, 메모리, 스토리지에 적합한 구성으로 VM을 배포해야 합니다. AlloyDB Omni 데이터베이스 파일을 수용하기 위해 시스템 디스크 크기를 20GB로 늘린 기본 Debian 이미지를 사용합니다.

시작된 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 VM을 만듭니다.

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 설치

생성된 VM에 연결합니다.

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:~$

연결된 터미널에서 다음 명령어를 실행합니다.

VM에 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:~$ 

VM에 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 VM에 연결하고 데이터베이스 만들기

Cloud Shell 세션에서 다음을 실행합니다.

gcloud config set project $(gcloud config get-value project)

AlloyDB Omni VM에 연결합니다.

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 VM에서 다음을 실행합니다.

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 VM에서 다음을 실행합니다.

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 VM에서 다음을 실행합니다.

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

신뢰할 수 있는 실행 시간을 얻으려면 테스트 쿼리를 여러 번 실행하는 것이 좋습니다.결과를 반환하는 데 걸리는 평균 시간은 약 94ms입니다. 다음 단계에서는 AlloyDB 열 엔진을 사용 설정하고 성능이 개선되는지 확인합니다.

psql 세션을 종료합니다.

exit

6. 열 기반 엔진 사용 설정

이제 AlloyDB Omni에서 열 형식 엔진을 사용 설정해야 합니다.

AlloyDB Omni 매개변수 업데이트

AlloyDB Omni의 인스턴스 매개변수 'google_columnar_engine.enabled'를 'on'으로 전환해야 하며 다시 시작해야 합니다.

/var/alloydb/config 디렉터리의 postgresql.conf를 업데이트하고 인스턴스를 다시 시작합니다.

GCE VM에서 다음을 실행합니다.

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 데이터베이스에 연결

VM 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. 실적 비교

이제 열 기반 엔진 저장소를 채우고 성능을 확인할 수 있습니다.

자동 열 형식 저장소 채우기

기본적으로 스토어를 채우는 작업은 1시간마다 실행됩니다. 대기 시간을 줄이기 위해 이 시간을 10분으로 줄일 예정입니다.

GCE VM에서 다음을 실행합니다.

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 VM에서 다음을 실행합니다.

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 VM에서 다음을 실행합니다.

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 VM에서 다음을 실행합니다.

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

실행 시간이 94ms에서 14ms로 감소했습니다. 실행 시간이 개선되지 않으면 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 (열 스캔)'이 사용된 것을 확인할 수 있습니다. 이를 통해 응답 시간을 94ms에서 12ms로 개선할 수 있었습니다.

열 엔진에서 자동으로 채워진 콘텐츠를 삭제하려면 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 컨테이너를 다시 시작하면 모든 열 정보가 손실된 것을 확인할 수 있습니다.

셸 세션에서 다음을 실행합니다.

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)' 플래그를 추가하고 컨테이너를 다시 시작합니다.

셸 세션에서 다음을 실행합니다.

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 VM을 삭제할 수 있습니다.

GCE VM 삭제

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 VM에 AlloyDB Omni를 배포하는 방법
  • AlloyDB Omni에 연결하는 방법
  • AlloyDB Omni에 데이터를 로드하는 방법
  • 열 기반 엔진을 사용 설정하는 방법
  • 자동 모드에서 열 엔진을 확인하는 방법
  • 열 형식 스토어를 수동으로 채우는 방법

문서에서 열 엔진 사용에 관해 자세히 알아보세요.

10. 설문조사

결과:

본 튜토리얼을 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다. 읽은 다음 연습 활동을 완료할 계획입니다.