PolarDB可以通過OSS外表直接查詢存儲在OSS上的CSV格式數據,有效地降低存儲的成本。本文檔主要介紹了通過OSS外表訪問OSS數據的操作步驟。
前提條件
PolarDB集群版本需滿足如下條件之一:
PolarDB MySQL版為8.0.1版本且修訂版本為8.0.1.1.25.4及以上。
PolarDB MySQL版為8.0.2版本且修訂版本為8.0.2.2.1及以上。
如何確認集群版本,詳情請參見查詢版本號。
技術原理
通過OSS外表,您可以將CSV格式的查詢頻度低的數據(稱為冷數據)存儲到OSS引擎上,并對冷數據進行查詢和分析。具體原理如下:
CSV格式的數據支持的數據類型包括數值類型、日期和時間類型、字符串類型以及NULL值。具體如下:
目前不支持地理空間數據類型。
目前不支持查詢CSV格式的壓縮文件。
PolarDB MySQL版為8.0.1版本且修訂版本為8.0.1.1.28及以上,或PolarDB MySQL版為8.0.2版本且修訂版本為8.0.2.2.5及以上時,支持使用NULL值。
數值類型
類型
大小
數據范圍(有符號)
數據范圍(無符號)
說明
TINYINT
1 Byte
-128~127
0~255
小整數值
SMALLINT
2 Bytes
-32768~32767
0~65535
大整數值
MEDIUMINT
3 Bytes
-8388608~8388607
0~16777215
大整數值
INT或INTEGER
4 Bytes
-2147483648~2147483647
0~4294967295
大整數值
BIGINT
8 Bytes
-9,223,372,036,854,775,808~9223372036854775807
0~18446744073709551615
極大整數值
FLOAT
4 Bytes
-3.402823466 E+38~-1.175494351E-38;0;1.175494351E-38~3.402823466351E+38
0;1.175494351E-38~3.402823466E+38
單精度浮點數值
DOUBLE
8 Bytes
-2.2250738585072014E-308~-1.7976931348623157E+308;0;1.7976931348623157E+308~2.2250738585072014E-308
0;1.7976931348623157E+308~2.2250738585072014E-308
雙精度浮點數值
DECIMAL
對于DECIMAL(M,D) ,如果M>D,為M+2;否則為D+2
依賴于M和D的值
依賴于M和D的值
小數值
日期和時間類型
類型
大小
數據范圍
數據格式
說明
DATE
3 Bytes
1000-01-01~9999-12-31
YYYY-MM-DD
日期值
TIME
3 Bytes
-838:59:59~838:59:59
HH:MM:SS
時間值或持續時間
YEAR
1 Byte
1901~2155
YYYY
年份值
DATETIME
8 Bytes
1000-01-01 00:00:00~9999-12-31 23:59:59
YYYY-MM-DD HH:MM:SS
混合日期和時間值
說明該類型中的月份和日期必須是兩位數。例如,2020年1月1日要寫成2020-01-01 ,而不能寫成2020-1-1,否則該查詢下推到OSS后無法被正確執行。
TIMESTAMP
4 Bytes
1970-01-01 00:00:00~2038-01-19 03:14:07
YYYY-MM-DD HH:MM:SS
時間戳(混合日期和時間值)
說明該類型中的月份和日期必須是兩位數。例如,2020年1月1日要寫成2020-01-01 ,而不能寫成2020-1-1,否則該查詢下推到OSS后無法被正確執行。
字符串類型
類型
大小
說明
CHAR
0~255 Bytes
定長字符串
VARCHAR
0~65535 Bytes
變長字符串
TINYBLOB
0~255 Bytes
不超過255個字符的二進制字符串
TINYTEXT
0~255 Bytes
短文本字符串
BLOB
0~65535 Bytes
二進制形式的長文本數據
TEXT
0~65535 Bytes
長文本數據
MEDIUMBLOB
0~16777215 Bytes
二進制形式的中等長度文本數據
MEDIUMTEXT
0~16777215 Bytes
中等長度文本數據
LONGBLOB
0~4294967295 Bytes
二進制形式的極大文本數據
LONGTEXT
0~4294967295 Bytes
極大文本數據
NULL值
插入NULL值。
在OSS外表中插入NULL值。
如果在OSS外表中插入NULL值,則需要在建表時指明對應的NULL值標記,即
NULL_MARKER
。OSS外表的NULL_MARKER
值默認為NULL,您可以通過show create table
語句來查看NULL值標記:show create table t1;
查詢結果如下:
show create table t1; +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | t1 | CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL ) ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ CONNECTION='server_name' | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
在CSV格式的文件中插入NULL值。
如果在CSV格式的文件中需要在某一字段對應的位置插入
NULL_MARKER
,且NULL_MARKER
兩端不添加雙引號,則PolarDB會把該值識別為NULL。說明當您在
NULL_MARKER
兩端添加雙引號,則PolarDB會識別為字符串,通過is_null
語句無法查出NULL值,且如果CSV文件中被賦予NULL值的參數與OSS外表中對應的參數類型不匹配,則會報錯。NULL_MARKER
不能設置為純數字,也不能設置為空,且不能含有以下四種字符:"
、\n
、\r
和,
示例:創建OSS外表的建表語句如下:
CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `time` timestamp NULL DEFAULT NULL ) ENGINE=CSV NULL_MARKER='NULL' CONNECTION='server_name';
假設對應的數據文件內容如下:
1,"xiaohong","2022-01-01 00:00:00" NULL,"xiaoming","2022-02-01 00:00:00" 3,NULL,"2022-03-01 00:00:00" 4,"xiaowang",NULL
則通過OSS外表查詢的OSS數據如下:
select * from t1; +------+----------+---------------------+ | id | name | time | +------+----------+---------------------+ | 1 | xiaohong | 2022-01-01 00:00:00 | | NULL | xiaoming | 2022-02-01 00:00:00 | | 3 | NULL | 2022-03-01 00:00:00 | | 4 | xiaowang | NULL | +------+----------+---------------------+ 4 rows in set (0.00 sec)
讀取NULL值。
從CSV格式的數據文件中讀取數據時,如果CSV中的值為NULL,且OSS外表中對應的值可以為NULL時,則當前字段直接設置為NULL。
從CSV格式的數據文件中讀取數據時,如果CSV中的值為NULL,但OSS外表中對應的值設置為NOT NULL時,即CSV中的數據內容與OSS外表中定義的內容沖突。則會根據您設置的語法校驗規則返回不同的結果。
當您將語法校驗規則
sql_mode
設置為STRICT_TRANS_TABLES
時,則會報錯。當您將語法校驗規則
sql_mode
設置為除STRICT_TRANS_TABLES
之外的其他模式時,如果當前字段有默認值,則當前字段的值會設置為默認值。如果沒有默認值,則當前字段會根據字段類型被賦予MySQL的默認值,詳情請參見數據類型默認值。且會有warning提示,您可以通過show warnings;
命令查看warning提示詳細信息。
說明您可以通過
show variables like "sql_mode";
命令查看當前的語法校驗規則。且可以在控制臺的參數配置中通過修改sql_mode
參數的值來修改當前的語法校驗規則,具體請參見修改參數值。示例:創建一張OSS外表
t
,將id
字段設置為NOT NULL,并且沒有默認值。CREATE TABLE `t` ( `id` int(11) NOT NULL ) ENGINE=CSV CONNECTION="server_name";
假設CSV格式的數據文件
t.CSV
中的內容為:NULL 2
通過OSS外表讀取CSV格式文件中的數據會有以下兩種情況:
當
sql_mode
設置為STRICT_TRANS_TABLES
時,執行如下命令,查詢CSV格式文件中的數據:select * from t;
報錯信息如下:
ERROR 1364 (HY000): Field 'id' doesn't have a default value
當
sql_mode
設置為除STRICT_TRANS_TABLES
之外的模式時,執行如下命令,查詢CSV格式文件中的數據:select * from t;
查詢結果如下:
+----+ | id | +----+ | 0 | | 2 | +----+ 2 rows in set, 1 warning (0.00 sec)
其中,0為MySQL默認值。
執行以下命令,查看warning提示信息:
show warnings;
查詢結果如下:
+---------+------+-----------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------+ | Warning | 1364 | Field 'id' doesn't have a default value | +---------+------+-----------------------------------------+ 1 row in set (0.00 sec)
使用限制
目前通過OSS外表僅支持查詢CSV格式的數據。
目前針對OSS外表的語句只支持CREATE、SELECT、DROP三種。
說明DROP操作不會刪除OSS上的數據文件,僅刪除PolarDB上的表信息。
OSS外表目前不支持索引、分區和事務。
參數說明
您可以在控制臺的參數配置頁面查看或修改以下參數:
參數名稱 | 級別 | 參數說明 |
loose_csv_oss_buff_size | 會話參數 | 當前一個OSS線程所占用的內存大小。默認值為134217728。單位:Byte。 取值范圍:4096~134217728 |
loose_csv_max_oss_threads | 全局參數 | 當前允許運行的OSS線程數量。默認值為1。 取值范圍:1~100 |
根據以上兩個參數可以計算出OSS功能占用的總內存最大為:loose_csv_max_oss_threads * loose_csv_oss_buff_size
使用OSS功能時,OSS占用的總內存盡量不要超過當前節點內存的5%,否則可能會出現內存溢出問題。
操作步驟
上傳CSV格式的數據至OSS。
您可以通過命令行工具ossutil將本地CSV格式的數據上傳到遠程OSS引擎上。
說明上傳CSV文件的OSS目錄需要與OSS server中
DATABASE
或oss_prefix
的目錄保持一致。上傳的CSV文件名需要設置為
外表名.CSV
,且文件名后綴CSV必須是大寫格式。例如,創建的OSS外表為t1
,則上傳的CSV文件名需要設置為t1.CSV
。CSV文件中的數據字段與OSS外表字段需要匹配。例如:創建的OSS外表
t1
表中只有一個字段id
,類型為INT
。則上傳的CSV文件中也只能有一個INT
類型的字段。建議您直接上傳本地MySQL的數據文件,并依據表定義創建對應的OSS外表。
添加OSS連接信息。
您可以通過創建OSS server來添加OSS連接信息。
說明通過其他方式連接OSS的功能由于存在安全風險已經被禁用。目前僅支持通過創建OSS server的方式來添加OSS連接信息,并與OSS建立連接。
若PolarDB MySQL版為8.0.1版本且修訂版本為8.0.1.1.28及以上。或PolarDB MySQL版為8.0.2版本且修訂版本為8.0.2.2.5及以上時,語法如下:
CREATE SERVER <server_name> FOREIGN DATA WRAPPER oss OPTIONS ( EXTRA_SERVER_INFO '{"oss_endpoint": "<my_oss_endpoint>","oss_bucket": "<my_oss_bucket>","oss_access_key_id": "<my_oss_access_key_id>","oss_access_key_secret": "<my_oss_access_key_secret>","oss_prefix":"<my_oss_prefix>","oss_sts_token":"<my_oss_sts_token>"}' );
說明PolarDB MySQL版為8.0.1版本且修訂版本為8.0.1.1.29及以上,或PolarDB MySQL版為8.0.2版本且修訂版本為8.0.2.2.6及以上時,支持使用
my_oss_sts_token
參數。該語法支持
DATABASE
參數,若您創建的OSS server中既存在DATABASE
參數,又存在my_oss_prefix
參數,則最終查找文件的路徑為my_oss_prefix/DATABASE
。添加DATABASE
參數的方法請參見下文中的內容。
參數說明如下表所示:
參數名稱
參數類型
是否必填
參數說明
server_name
字符串
是
OSS server名稱。
說明該參數為全局參數,且全局唯一。該參數不區分大小寫,最大長度不超過64個字符,超過64個字符的名稱會被自動截斷。您可以將OSS server名稱指定為帶引號的字符串。
my_oss_endpoint
字符串
是
OSS對應區域的域名。
說明如果是從阿里云的主機訪問數據庫,應該使用內網域名(即帶有“internal”的域名),避免產生公網流量。
例如:華東1(杭州)OSS節點的內網域名:
oss-cn-xxx-internal.aliyuncs.com
my_oss_bucket
字符串
是
數據文件所在OSS的bucket,需要通過OSS預先創建。
說明OSS的bucket和PolarDB最好在同一個可用區內,以減少兩者之間的網絡延遲。
my_oss_access_key_id
字符串
是
RAM用戶或阿里云賬號的AccessKey ID。
如何創建AccessKey請參見創建AccessKey。
my_oss_access_key_secret
字符串
是
RAM用戶或阿里云賬號的AccessKey Secret。
如何創建AccessKey請參見創建AccessKey。
my_oss_prefix
字符串
否
當前CSV數據文件在OSS中的目錄。
my_oss_sts_token
字符串
否
STS臨時訪問憑證。
說明當使用STS臨時訪問憑證訪問OSS時,該參數必填。
my_oss_sts_token
參數值有默認的過期時間。如果my_oss_sts_token
已過期,您需要通過以下命令重置EXTRA_SERVER_INFO
中的全部參數值。ALTER SERVER server_name OPTIONS(EXTRA_SERVER_INFO '{"oss_endpoint": "<my_oss_endpoint>", "oss_bucket": "<my_oss_bucket>", "oss_access_key_id": "<my_oss_access_key_id>", "oss_access_key_secret": "<my_oss_access_key_secret>", "oss_prefix":"<my_oss_prefix>", "oss_sts_token": "<my_oss_sts_token>"}');
說明創建OSS server時需要SERVERS_ADMIN權限,您可以通過
show grants for 當前用戶
命令查看當前用戶是否具有SERVERS_ADMIN權限。目前,高權限賬戶默認具有該權限,并且高權限賬戶可以給低權限賬戶賦予該權限。如果您當前沒有SERVERS_ADMIN權限,會提示錯誤信息:
Access denied; you need (at least one of) the SERVERS_ADMIN OR SUPER privilege(s) for this operation
。如果您是普通賬戶沒有SERVERS_ADMIN權限,可以使用高權限賬戶執行:
GRANT SERVERS_ADMIN ON *.* TO `users`@`%` WITH GRANT OPTION
;如果您是高權限賬戶沒有SERVERS_ADMIN權限,您可以點擊集群列表找到所需要設置的集群ID/名稱>配置與管理>賬號管理>重置權限以重置權限,等待一段時間后,再查看高權限賬戶,此時就有SERVERS_ADMIN權限了。如果您是高權限用戶,可以通過
SELECT Server_name, Extra_server_info FROM mysql.servers;
命令查看您創建的OSS Server信息,且oss_access_key_id
和oss_access_key_secret
參數信息因為涉及安全信息會被加密處理,無法查看其詳細信息。
若PolarDB MySQL版為8.0.1版本且修訂版本在8.0.1.1.25.4至8.0.1.1.28之間,或PolarDB MySQL版為8.0.2版本且修訂版本在8.0.2.2.1至8.0.2.2.5之間時,語法如下:
CREATE SERVER <server_name> FOREIGN DATA WRAPPER oss OPTIONS (DATABASE '<my_database_name>', EXTRA_SERVER_INFO '{"oss_endpoint": "<my_oss_endpoint>","oss_bucket": "<my_oss_bucket>","oss_access_key_id":"<my_oss_access_key_id>","oss_access_key_secret":"<my_oss_access_key_secret>"}' );
說明該版本的語法不支持
oss_prefix
參數。參數說明如下表所示:
參數名稱
參數類型
是否必填
參數說明
server_name
字符串
是
OSS server名稱。
說明該參數為全局參數,且全局唯一。該參數不區分大小寫,最大長度不超過64個字符,超過64個字符的名稱會被自動截斷。您可以將OSS server名稱指定為帶引號的字符串。
my_database_name
字符串
否
當前CSV數據文件在OSS中的目錄名稱。
my_oss_endpoint
字符串
是
OSS對應區域的域名。
說明如果是從阿里云的主機訪問數據庫,應該使用內網域名(即帶有“internal”的域名),避免產生公網流量。
例如:
oss-cn-xxx-internal.aliyuncs.com
my_oss_bucket
字符串
是
數據文件所在OSS的bucket,需要通過OSS預先創建。
my_oss_access_key_id
字符串
是
RAM用戶或阿里云賬號的AccessKey ID。
如何創建AccessKey請參見創建AccessKey。
my_oss_access_key_secret
字符串
是
RAM用戶或阿里云賬號的AccessKey Secret。
如何創建AccessKey請參見創建AccessKey。
創建OSS外表。
定義了OSS Server之后,您需要在PolarDB上創建OSS外表,與OSS建立連接。示例如下:
create table t1 (id int) engine=csv connection="connection_string";
其中,
connection_string
由以下內容組成,且使用“/”來進行連接:OSS Server名稱。
(可選)OSS上的數據文件路徑。
說明當PolarDB MySQL版為8.0.1版本且修訂版本為8.0.1.1.28及以上。或PolarDB MySQL版為8.0.2版本且修訂版本為8.0.2.2.5及以上時,支持配置OSS上的數據文件路徑。
(可選)數據文件名稱。
說明數據文件名稱后面不能有
.CSV
后綴。
示例:
create table t1 (id int) engine=csv connection="server_name/a/b/c/d/t1";
通過示例可以看出:OSS上的數據文件路徑為
oss_prefix/a/b/c/d/
,數據文件為t1.CSV
。說明您可以只使用數據文件名稱來指定OSS外表對應的數據文件。例如:
create table t1 (id int) engine=csv connection="server_name/t2"
,則PolarDB會在OSS上的oss_prefix路徑下查找t2.CSV
的文件。如果您在
connection_string
中添加了OSS上的數據文件路徑,則您必須添加對應的數據文件名稱。否則,查找對應的文件時會將路徑的最后一段識別為文件名稱。如果不指定數據文件名稱,則當前表對應的OSS文件為
當前表名.CSV
;如果指定數據文件名稱,則當前表對應的OSS文件為指定的數據文件名稱.CSV
。
OSS外表創建完成后,您可以通過
show create table
命令查看已創建的表。請檢查已創建的表的引擎是否為CSV,如果不是,可能是您當前的PolarDB版本過低,不支持OSS引擎。數據查詢。
以上述步驟示例中的
t1
表為例進行說明。#查詢t1表內的數據數量 SELECT count(*) FROM t1; #范圍查詢 SELECT id FROM t1 WHERE id < 10 AND id > 1; #點查 SELECT id FROM t1 where id = 3; #多表join SELECT id FROM t1 left join t2 on t1.id = t2.id WHERE t2.name like "%er%";
查詢數據的過程中,常見的報錯信息及報錯原因請參見下表:
說明如果在查詢數據的過程中,沒有報錯信息但有警告信息時,您需要通過
SHOW WARNINGS;
命令查看報錯信息。報錯信息
報錯原因
解決方案
OSS error: No corresponding data file on the OSS engine.
OSS上沒有找到對應的數據文件。
您需要根據上述規則檢查OSS上對應的路徑下是否存在數據文件。
若存在,確認數據文件格式是否符合命名規則。即符合
外表名.CSV
,且文件名后綴CSV必須為大寫格式。若不存在,則需要將數據文件上傳至目標路徑。
There is not enough memory space for OSS transmission. Currently requested memory %d.
沒有足夠的空間進行OSS查詢。
您可以通過以下兩種方式中的任意一種來修復該錯誤:
在控制臺的參數配置中通過修改
loose_csv_max_oss_threads
參數值來運行更多的OSS線程。通過flush table關閉某些OSS表的線程。
ERROR 8054 (HY000): OSS error: error message : Couldn't connect to server.Failed connect to aliyun-mysql-oss.oss-cn-hangzhou-internal.aliyuncs.com:80;
當前的數據庫實例無法連接OSS服務器。
檢查當前的數據庫實例與OSS bucket是否在同一個可用區。
如果不在同一個可用區,則需要將當前的數據庫實例與OSS bucket放在同一個可用區。
如果在同一個可用區,您可以將endpoint修改為公網的endpoint。如果endpoint修改后仍然報錯,請聯系阿里云技術支持解決。
查詢優化
OSS引擎在查詢過程中,可以將部分的查詢條件下推到遠程引擎OSS上執行,以獲得更好的查詢效率,這個優化被稱之為engine condition pushdown
。可以下推的限制條件如下:
目前僅支持UTF-8編碼格式的CSV文本文件。
SQL語句中僅支持以下幾種類型的算子和算數表達式:
比較算子:
>
、<
、>=
、<=
、==
邏輯算子:
LIKE
、IN
、AND
、OR
算數表達式:
+
、-
、*
、/
僅支持單文件查詢,不支持join、order by、group by、having子查詢。
WHERE語句里不能包含聚合條件,例如
where max(age) > 100
是不允許的。支持的最大列數是1000,SQL中最大列名長度不能超過1024個字節。
在LIKE語句中,支持最多5個
%
通配符。在IN語句中,最多支持1024個常量項。
CSV文件支持單行及單列的最大字符數均為256 KB。
SQL最大長度為16 KB,WHERE語句后面的表達式個數最多20個,聚合操作最多100個。
該功能默認關閉,如需使用您可以通過執行SET SESSION optimizer_switch='engine_condition_pushdown=on';
命令開啟該功能。
符合以上條件的查詢會被下推到OSS引擎去執行。您可以通過OSS外表的執行計劃來查看哪些查詢條件被下推到OSS引擎上執行。
通過
explain
查看OSS外表的執行計劃。示例如下:EXPLAIN SELECT count(*) FROM `t1` WHERE `id` > 5 AND `id` < 100 AND `name` LIKE "%1%%%%%" GROUP BY `id` ORDER BY `id` DESC; +----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+----------------------------------------------------------------------------------------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+----------------------------------------------------------------------------------------------------------------------------------+ | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 15000 | 1.23 | Using where; With pushed engine condition ((`test`.`t1`.`id` > 5) and (`test`.`t1`.`id` < 100)); Using temporary; Using filesort | +----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+----------------------------------------------------------------------------------------------------------------------------------+ 1 row in set, 1 warning (0.00 sec)
其中,
With pushed engine condition
后面的條件可以被下推到遠程OSS引擎上執行,其余的條件`name` LIKE "%1%%%%%"
、GROUP BY `id` ORDER BY `id` DESC
不能被下推到OSS引擎上執行,只會在本地OSS server上執行。通過
tree
格式查看OSS外表的執行計劃。示例如下:EXPLAIN FORMAT=tree SELECT SELECT count(*) FROM `t1` WHERE `id` > 5 AND `id` < 100 AND `name` LIKE "%1%%%%%" Y `id` ORDER BY `id` DESC; +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | EXPLAIN | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | -> Sort: <temporary>.id DESC -> Table scan on <temporary> -> Aggregate using temporary table -> Filter: (t1.`name` like '%1%%%%%') (cost=1690.00 rows=185) -> Table scan on t1, extra ( engine conditions: ((t1.id > 5) and (t1.id < 100)) ) (cost=1690.00 rows=15000) | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
其中,
engine conditions:
后面的條件可以被下推到遠程OSS引擎上執行,其余的條件`name` LIKE "%1%%%%%"
、GROUP BY `id` ORDER BY `id` DESC
不能被下推到OSS引擎上執行,只會在本地OSS server上執行。說明集群版本需為PolarDB MySQL版8.0.2版本,您可以通過查詢版本號確認集群版本。
通過
Json
格式查看OSS外表的執行計劃。示例如下:EXPLAIN FORMAT=json SELECT count(*) FROM `t1` WHERE `id` > 5 AND `id` < 100 AND `name` LIKE "%1%%%%%" GROUP BY `id` ORDER BY `id` DESC; +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | EXPLAIN | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | { "query_block": { "select_id": 1, "cost_info": { "query_cost": "1875.13" }, "ordering_operation": { "using_filesort": false, "grouping_operation": { "using_temporary_table": true, "using_filesort": true, "cost_info": { "sort_cost": "185.13" }, "table": { "table_name": "t1", "access_type": "ALL", "rows_examined_per_scan": 15000, "rows_produced_per_join": 185, "filtered": "1.23", "engine_condition": "((`test`.`t1`.`id` > 5) and (`test`.`t1`.`id` < 100))", "cost_info": { "read_cost": "1671.49", "eval_cost": "18.51", "prefix_cost": "1690.00", "data_read_per_join": "146K" }, "used_columns": [ "id", "name" ], "attached_condition": "(`test`.`t1`.`name` like '%1%%%%%')" } } } } } | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set, 1 warning (0.00 sec)
同上,
engine conditions:
后面的條件可以被下推到遠程OSS引擎上執行,其余的條件`name` LIKE "%1%%%%%"
、GROUP BY `id` ORDER BY `id` DESC
不能被下推到OSS引擎上執行,只會在本地OSS server上執行。
如果出現以下錯誤,則表示當前OSS數據文件中的某些字符不符合OSS條件下推的要求。
OSS error: The current query does not support engine condition pushdown. You need to use NO_ECP() hint or set optimizer_switch = 'engine_condition_pushdown=OFF' to turn off the condition push down function.
您可以通過hints或者optimizer_switch手動關閉條件下推功能。
hints
通過hints可以針對某個查詢關閉條件下推功能。例如:關閉
t1
表的查詢下推功能:SELECT /*+ NO_ECP(t1) */ `j` FROM `t1` WHERE `j` LIKE "%c%" LIMIT 10;
optimizer_switch
通過optimizer_switch可以針對當前session,關閉所有查詢的條件下推功能。
SET SESSION optimizer_switch='engine_condition_pushdown=off'; #將engine_condition_pushdown設置為off,表示關閉當前session下所有查詢的條件下推功能。
您可以通過以下命令查看當前系統的optimizer_switch狀態,以此來判斷當前session下所有查詢的條件下推功能狀態:
select @@optimizer_switch;
多節點之間同步OSS server信息
目前,PolarDB集群的主節點和只讀節點共用一個OSS server,以保證在兩個節點上都可以訪問OSS上的數據。且兩個節點間OSS Server信息同步是無鎖的,以保證在兩個節點上的操作不會互相影響。
當您修改OSS Server信息后,修改內容會無鎖地同步到只讀節點,如果只讀節點上有線程持有OSS Server的鎖,則可能會導致OSS server信息同步時間延遲。此時,您可以通過執行/*force_node='pi-bpxxxxxxxx'*/ flush privileges;
或/*force_node='pi-bpxxxxxxxx'*/flush table oss_foreign_table;
命令來手動更新只讀節點的OSS server信息。