執行 MySQL 聯合查詢
資料分析師可以直接從 BigQuery 即時查詢 MySQL 中的關聯資料,不必複製或移動資料。
BigQuery MySQL 聯合查詢會使用 BigQuery Connection API 連線至 MySQL 資料庫引擎。接著,您可以使用 EXTERNAL_QUERY 函式,將 SQL 查詢直接傳送至 MySQL 執行,結果會直接串流傳回。
限制
MySQL 聯合查詢有下列限制:
- 您只能透過
EXTERNAL_QUERY函式執行唯讀查詢。不支援資料定義語言 (DDL) 和 data manipulation language (DML) 陳述式。 - 只能透過
EXTERNAL_QUERY函式存取聯合。不支援建立直接對應至 MySQL 資料表的 BigQuery 外部資料表或永久資料集。 - 聯合查詢的延遲時間可能明顯高於直接在 MySQL 中執行查詢。
- 基礎連線服務可能會讓閒置連線進入休眠狀態。閒置一段時間後,使用 MySQL 連線的第一個查詢可能需要超過一分鐘才能執行,因為連接器需要初始化。
- 不支援 DNS 對接。您必須使用虛擬私有雲網路中的 IP 位址或可完整解析的主機名稱連線。
- MySQL SQL 查詢必須為包含函式結果或運算式的任何資料欄 (例如
SELECT COUNT(*) AS total_count) 指定明確的資料欄別名。未設定別名的運算式會產生含有特殊字元的資料欄名稱,這在 BigQuery 資料表結構定義中無效。 - 如果查詢專案中的 Compute Engine API 使用量受到 VPC Service Controls 限制,且連線使用網路連結,聯合查詢就會失敗。請務必設定適當的 VPC Service Controls 輸入和輸出規則。
MySQL 不支援其他 SQL 下推。外部 BigQuery 查詢中的篩選器和匯總不會向下推送至
EXTERNAL_QUERY函式中的內部查詢。您必須直接在內部 MySQL SQL 陳述式中指定述詞和資料欄投影,限制透過網路傳輸的資料列和資料欄。僅支援 MySQL 資料庫使用者名稱和密碼驗證。不支援第三方識別資訊提供者、Kerberos 和雲端服務供應商 IAM 驗證。
如果查詢選取 32 位元整數資料欄 (
TINYINT、SMALLINT和BOOLEAN/TINYINT(1)) 或單精度浮點數資料欄 (FLOAT),CREATE TABLE ... AS SELECT(CTAS) 陳述式會失敗,並顯示Unsupported type INT32或Unsupported type FLOAT錯誤。如要將查詢結果儲存至新的 BigQuery 資料表,請在查詢中明確將整數資料欄轉換為INT64,並將浮點數資料欄轉換為FLOAT64:CREATE TABLE mydataset.mytable AS SELECT CAST(tiny_col AS INT64) AS tiny_col, CAST(small_col AS INT64) AS small_col, ... FROM EXTERNAL_QUERY(...);
使用
INSERT INTO <table> SELECT ...插入現有資料表時,不需手動轉換即可成功,因為 BigQuery 會自動擴大INT32和FLOAT值,以符合目標資料表的INT64和FLOAT64欄。雖然 MySQL
DECIMAL和NUMERIC資料欄會對應至BIGNUMERIC(76, 38),但 MySQL 允許的精確度最高可達 65。如果值的整數位數超過 38 位 (精確度減去小數位數大於 38),就會超出BIGNUMERIC整數範圍,查詢會在執行階段失敗。如要查詢整數位數超過 38 位的數值,請在EXTERNAL_QUERY陳述式中將其轉換為CHAR或VARCHAR。TIME資料類型會將小數秒 (微秒) 值截斷為整秒 (例如12:34:56.789123變成12:34:56)。此外,MySQLTIME支援從-838:59:59到838:59:59的經過時間,而 BigQueryTIME僅支援從00:00:00到23:59:59.999999的時間值。如果值超出00:00:00到23:59:59的範圍,會導致執行階段查詢錯誤。如需微秒精確度或經過時間長度值,請在EXTERNAL_QUERY陳述式中將資料欄轉換為CHAR或VARCHAR。1582 年 10 月 15 日之前的日期和時間戳記,會因歷史上的公曆轉換而有 10 天的日曆偏移。如要保留 1582 年之前的確切歷史日期,請在
EXTERNAL_QUERY陳述式中將其轉換為CHAR或VARCHAR。
支援的 MySQL 環境和版本
查詢聯合支援下列部署環境中的 MySQL 資料庫:
- 可透過公開 IP 位址或網路連結 (經由 Cloud VPN 或 Cloud Interconnect) 存取的雲端託管或地端部署 MySQL 資料庫
- 在 Compute Engine 或其他基礎架構上自行託管的 MySQL 執行個體
- MySQL 8.4 LTS 和 8.0
事前準備
確認 BigQuery 管理員已建立 MySQL 連線,並與您共用。
必要的角色
如要取得查詢 MySQL 所需的權限,請要求管理員授予您專案的 BigQuery 連線使用者 (roles/bigquery.connectionUser) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
查詢資料
如要從 GoogleSQL 查詢向 MySQL 傳送聯合查詢,請使用 EXTERNAL_QUERY 函式。
以下範例是聯合查詢,會將 BigQuery 中名為 mydataset.customers 的客戶記錄,與 MySQL 中的交易銷售訂單彙整:
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/mysql_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;
查看 MySQL 資料表結構定義
您可以透過 EXTERNAL_QUERY 查詢 MySQL INFORMATION_SCHEMA 檢視表,在執行分析前檢查資料庫中繼資料、探索資料表,以及查看資料欄結構定義。
列出所有資料庫
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', '''SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.SCHEMATA''');
列出資料庫中的資料表
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', """SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'DATABASE_NAME'""");
查看資料表中的資料欄和資料類型
SELECT * FROM EXTERNAL_QUERY( 'projects/PROJECT_ID/locations/LOCATION/connections/CONNECTION_ID', """SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'DATABASE_NAME' AND TABLE_NAME = 'TABLE_NAME'""");
資料類型對應
執行聯合查詢時,BigQuery 會根據下表,將 MySQL 資料轉換為 GoogleSQL 資料類型:
| MySQL 資料類型 | BigQuery 資料類型 |
|---|---|
| 數值類型 | |
BOOLEAN、BOOL、TINYINT(1) |
INT64 (互動式查詢;請參閱CREATE TABLE ... AS SELECT的限制) |
TINYINT、SMALLINT |
INT64 (互動式查詢;請參閱CREATE TABLE ... AS SELECT的限制) |
MEDIUMINT、INT、INTEGER |
INT64 |
BIGINT |
INT64 |
BIGINT UNSIGNED、BIGINT ZEROFILL、SERIAL |
BIGNUMERIC(76, 38) |
DECIMAL、DEC、NUMERIC、FIXED |
BIGNUMERIC(76, 38) |
FLOAT |
FLOAT64 (互動式查詢;請參閱CREATE TABLE ... AS SELECT的限制) |
DOUBLE、DOUBLE PRECISION、REAL |
FLOAT64 |
| 日期和時間類型 | |
DATE |
DATE |
DATETIME |
DATETIME |
TIMESTAMP |
TIMESTAMP |
TIME |
TIME |
| 字串和文字類型 | |
CHAR |
STRING |
VARCHAR |
STRING |
BINARY |
BYTES |
VARBINARY |
BYTES |
TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB |
BYTES |
TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT |
STRING |
ENUM |
STRING |
SET |
STRING |
定價
執行聯合查詢的費用取決於下列三項因素:
- 在 MySQL 執行查詢的運算費用 (由 MySQL 資料庫供應商或託管環境收取)
- 將查詢結果從 MySQL 移轉至 BigQuery 的頻寬費用 (資料庫代管服務供應商收取的輸出網路費用)
- 在 BigQuery 執行查詢的運算費用
任何 MySQL 運算和輸出費用,都會由 MySQL 供應商或基礎架構主機直接收取,而非 Google。為限制頻寬成本,建議您在 EXTERNAL_QUERY 陳述式中編寫查詢,排除所有不需要用來計算最終結果的資料欄和資料列。
在 BigQuery 執行聯合查詢不會產生額外費用。如要進一步瞭解 BigQuery 定價,請參閱「定價」一文。
如果連線使用 Google Cloud 網路元件,可能也適用下列定價: