執行 PostgreSQL 聯合查詢
資料分析師可以直接從 BigQuery 即時查詢 PostgreSQL 中的關聯資料,不必複製或移動資料。
BigQuery PostgreSQL 聯合查詢會使用 BigQuery Connection API 連線至 PostgreSQL 資料庫引擎。接著,您可以使用 EXTERNAL_QUERY 函式,將 SQL 查詢直接傳送至 PostgreSQL 執行,結果會直接串流傳回。
限制
PostgreSQL 聯合查詢有下列限制:
- 您只能透過
EXTERNAL_QUERY函式執行唯讀查詢。不支援資料定義語言 (DDL) 和 data manipulation language (DML) 陳述式。 - 只能透過
EXTERNAL_QUERY函式存取聯合。不支援建立直接對應至 PostgreSQL 資料表的 BigQuery 外部資料表或永久資料集。 - 聯合查詢的延遲時間可能明顯高於直接在 PostgreSQL 執行查詢。
- 基礎連線服務可能會讓閒置連線進入休眠狀態。在閒置一段時間後,使用 PostgreSQL 連線的第一個查詢可能需要超過一分鐘才能執行,因為連接器需要初始化。
- 不支援 DNS 對接。您必須使用虛擬私有雲網路中的 IP 位址或可完整解析的主機名稱連線。
- PostgreSQL SQL 查詢必須為包含函式結果或運算式的任何資料欄 (例如
SELECT COUNT(*) AS total_count) 指定明確的資料欄別名。未加上別名的運算式會產生含有特殊字元的資料欄名稱,這在 BigQuery 資料表結構定義中無效。 - 如果查詢專案中的 Compute Engine API 使用量受到 VPC Service Controls 限制,且連線使用網路連結,聯合查詢就會失敗。請務必設定適當的 VPC Service Controls 輸入和輸出規則。
PostgreSQL 不支援其他 SQL 下推。外部 BigQuery 查詢中的篩選器和匯總不會向下推送至
EXTERNAL_QUERY函式中的內部查詢。您必須直接在內部 PostgreSQL SQL 陳述式中指定述詞和資料欄投影,限制透過網路傳輸的資料列和資料欄。僅支援 PostgreSQL 資料庫使用者名稱和密碼驗證。不支援第三方識別資訊提供者、Kerberos 和雲端服務供應商 IAM 驗證。
如果查詢選取 16 位元整數資料欄 (
int2、smallint、smallserial) 或單精度浮點數資料欄 (float4、real),CREATE TABLE ... AS SELECT(CTAS) 陳述式會失敗,並顯示Unsupported type INT32或Unsupported type FLOAT錯誤。如要將查詢結果儲存至新的 BigQuery 資料表,請在查詢中明確將整數資料欄轉換為INT64,並將浮點數資料欄轉換為FLOAT64:CREATE TABLE mydataset.mytable AS SELECT CAST(small_col AS INT64) AS small_col, CAST(real_col AS FLOAT64) AS real_col, ... FROM EXTERNAL_QUERY(...);
使用
INSERT INTO <table> SELECT ...插入現有資料表時,不需手動轉換即可成功,因為 BigQuery 會自動擴大INT32和FLOAT值,以符合目標資料表的INT64和FLOAT64欄。time [ without time zone ]和time with time zone(timetz) 都會將小數秒 (微秒) 值截斷為整數秒。如需微秒精確度,請在EXTERNAL_QUERY陳述式中,將資料欄格式化或轉換為text或varchar。所有 PostgreSQL
numeric和decimal資料欄都會對應至BIGNUMERIC(76, 38)。如果資料欄的小數位數大於 38,則會四捨五入至小數點後 38 位,而超過BIGNUMERIC範圍的值 (超過 38 個完整整數位數) 則會失敗,並顯示超出範圍錯誤。此外,系統不支援特殊值NaN、Infinity和-Infinity,且會在執行階段失敗。如要查詢整數部分較大、小數精確度較高或特殊值的數字,請在EXTERNAL_QUERY陳述式中將資料欄轉換為text。對應至 BigQuery
STRING時,固定長度的character(n)/char(n)(bpchar) 值會保留結尾空格,最長可達 n。由於歷史上曾改用公曆,1582 年 10 月 15 日之前的日期和時間戳記會出現 10 天的日曆偏移。在
EXTERNAL_QUERY陳述式中,將歷來日期轉換為text,以保留確切日期。
支援的 PostgreSQL 環境和版本
查詢聯合支援下列部署環境中的 PostgreSQL 資料庫:
- 可透過公開 IP 位址或網路連結 (透過 Cloud VPN 或 Cloud Interconnect) 存取的雲端託管或地端部署 PostgreSQL 資料庫
- 在 Compute Engine 或其他基礎架構上自行託管的 PostgreSQL 執行個體
- PostgreSQL 16 (建議) 和 PostgreSQL 15
事前準備
確認 BigQuery 管理員已建立 PostgreSQL 連線,並與您共用。
必要的角色
如要取得查詢 PostgreSQL 所需的權限,請要求管理員授予您專案的 BigQuery 連線使用者 (roles/bigquery.connectionUser) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
查詢資料
如要從 GoogleSQL 查詢傳送聯合查詢至 PostgreSQL,請使用 EXTERNAL_QUERY 函式。
以下範例是聯合查詢,會將 BigQuery 中名為 mydataset.customers 的客戶記錄,與 PostgreSQL 中的交易銷售訂單彙整:
SELECT c.customer_id, c.name, fo.first_order_date FROM mydataset.customers AS c LEFT OUTER JOIN EXTERNAL_QUERY( 'projects/my-project/locations/us-central1/connections/postgres_prod_conn', '''SELECT customer_id, MIN(order_date) AS first_order_date FROM orders GROUP BY customer_id''') AS fo ON fo.customer_id = c.customer_id GROUP BY c.customer_id, c.name, fo.first_order_date;
查看 PostgreSQL 資料表結構定義
您可以使用 EXTERNAL_QUERY 查詢 PostgreSQL information_schema 資料表,擷取資料庫中繼資料:
列出結構定義中的所有資料表
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', '''SELECT table_schema, table_name, table_type FROM information_schema.tables WHERE table_schema = 'SCHEMA_NAME' ORDER BY table_name''');
查看資料表中的資料欄和資料類型
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', '''SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema = 'SCHEMA_NAME' AND table_name = 'TABLE_NAME' ORDER BY ordinal_position''');
資料類型對應
執行聯合查詢時,BigQuery 會根據下表,將 PostgreSQL 資料轉換為 GoogleSQL 資料類型:
| PostgreSQL 資料類型 | BigQuery 資料類型 |
|---|---|
| 布林值類型 | |
bool、boolean |
BOOL |
| 數值類型 | |
int2、smallint、smallserial |
INT64 (互動式查詢;請參閱CREATE TABLE ... AS SELECT的限制) |
int4、integer、serial |
INT64 |
int8、bigint、bigserial |
INT64 |
numeric、decimal |
BIGNUMERIC(76, 38) |
float4、real |
FLOAT64 (互動式查詢;請參閱CREATE TABLE ... AS SELECT的限制) |
float8、double precision |
FLOAT64 |
| 日期和時間類型 | |
date |
DATE |
timestamp [ without time zone ] |
DATETIME |
timestamp with time zone、timestamptz |
TIMESTAMP |
time [ without time zone ] |
TIME |
time with time zone、timetz |
TIME |
| 字元和文字類型 | |
character(n)、char(n)、bpchar |
STRING |
character varying(n)、varchar(n) |
STRING |
text |
STRING |
定價
執行聯合查詢的費用取決於下列三項因素:
- 在 PostgreSQL 執行查詢的運算費用 (由 PostgreSQL 資料庫供應商或託管環境收取)
- 將查詢結果從 PostgreSQL 轉移至 BigQuery 的頻寬費用 (資料庫代管服務供應商收取的輸出網路費用)
- 在 BigQuery 執行查詢的運算費用
任何 PostgreSQL 運算和輸出費用,都會由 PostgreSQL 供應商或基礎架構主機直接收取,而非 Google。為限制頻寬成本,建議您在 EXTERNAL_QUERY 陳述式中編寫查詢,排除所有不需要用來計算最終結果的資料欄和資料列。
在 BigQuery 執行聯合查詢不會產生額外費用。如要進一步瞭解 BigQuery 定價,請參閱「定價」一文。
如果連線使用 Google Cloud 網路元件,可能也適用下列定價:
後續步驟
- 瞭解如何連線至 PostgreSQL。
- 進一步瞭解聯合查詢。
- 瞭解如何管理連結。
- 瞭解 AlloyDB 聯合查詢。
- 瞭解 Cloud SQL 聯合查詢。