本文介绍了OSS冷数据的查询加速功能。
背景信息
随着OSS应用的日益广泛,存储的数据量也迅速增加,查询性能低下问题日益突出,严重影响体验。尽管冷数据并行查询可以提供更快的查询速度,但在扫描OSS表的过程中,冷数据并行查询的高效需要消耗大量内存、连接数和网络带宽资源,业务体验仍然会受到一定影响。因此,我们急需一种能够快速过滤OSS表数据的方法,以提升查询性能。
为了解决这一问题,我们引入了OSS数据块过滤(OSS File Filter)功能。该功能根据查询条件排除不需要扫描的OSS数据块,从而减少需要扫描的数据量,大幅提升查询性能。这一创新不仅优化了资源使用效率,也显著增强了使用体验。
功能说明
查询加速功能通过收集每个归档数据块的统计信息生成过滤数据(filter data),并将其保存在OSS上。在查询过程中,系统会根据引擎下推的查询条件结合过滤数据,排除不需要扫描的数据块,从而减少数据扫描量并缩短查询时间。OSS冷数据可以通过OSS_FILE_FILTER对数据进行过滤。针对不同的数据类型OSS_FILE_FILTER采用了不同的过滤方式:数值类型通过比较数据块最小值和最大值统计信息来进行过滤;字符串类型则通过比较字符映射进行过滤。如果指定了过滤类型为BLOOM类型,则将使用布隆过滤器进行过滤。
对于有序或局部有序的数值类型数据,OSS_FILE_FILTER能够提供更优异的处理效果。然而,对于全局无序的数据,建议使用布隆过滤器,以实现更有效的过滤。
由于归档数据通常具有较好的时间序列,因此使用时间类型的列进行过滤可以显著提升查询性能。
前置条件
数据库引擎版本为MySQL 8.0.2,且内核小版本为8.0.2.2.25及以上。
已开启冷数据归档功能。
已连接数据库集群。
仅支持CSV格式的OSS冷数据创建 OSS_FILE_FILTER。
要在当前表上支持
OSS_FILE_FILTER,必须具有OSS META = 1的选项。通过SHOW CREATE TABLE命令,可以在CSV格式中查看当前表是否已开启OSS META。如果返回结果中包含OSS META=1,则表示当前表已开启OSS META。如需详细了解请参考冷数据DDL。SHOW CREATE TABLE t; *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) DEFAULT NULL ) /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ 1 row in set (0.00 sec)
使用限制
目前暂不支持在ePQ弹性并行查询的场景下使用OSS_FILE_FILTER过滤数据。
当前支持的OSS_FILE_FILTER函数:=、<=>、<、<=、>=、>、BETWEEN、LIKE、IS NULL、IS NOT NULL、LIKE只支持右百分号(LIKE 'ABC%')。
当前支持OSS_FILE_FILTER的数据类型:
类别
数据类型
整数
TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT,TINYINT UNSIGNED,SMALLINT UNSIGNED,MEDIUMINT UNSIGNED,INT UNSIGNE,BIGINT UNSIGNED浮点数
FLOAT,DOUBLE定点数
DECIMAL时间类型
DATE,DATETIME,TIME,TIMESTAMP字符串类型
CHAR,VARCHAR如果使用BLOOM FILTER则不限制列的数据类型。
如果字符串类型保存的是UUID值,建议使用BLOOM FILTER进行过滤。
对于字符串类型的列,只支持大小写敏感的比较方式。
支持多个条件之间的AND运算,但不支持多个条件之间的OR运算。
如果OSS表里没有数据,则不能使用OSS_FILE_FILTER查询加速。
操作步骤
请在控制台中将集群参数
loose_use_oss_meta设置为ON,开启USE_OSS_META功能,集群参数配置请参考设置集群参数和节点参数。请在控制台中将集群参数
loose_optimizer_switch设置为ENGINE_CONDITION_PUSHDOWN=ON,集群参数配置请参考设置集群参数和节点参数。请在控制台中将集群参数
loose_csv_oss_file_filter设置为ON,开启OSS_FILE_FILTER功能,集群参数配置请参考设置集群参数和节点参数。请确保数据库集群已成功连接。如尚未连接,请参考连接数据库集群相关文档进行连接操作,验证当前参数配置是否已成功应用。
-- 检查oss_file_filter是否设置成功 SHOW VARIABLES LIKE 'oss_file_filter'; -- 检查use_oss_meta是否设置成功 SHOW VARIABLES LIKE 'use_oss_meta'; -- 检查engine_condition_pushdown是否设置成功 SHOW VARIABLES LIKE 'optimizer_switch';
OSS_FILE_FILTER格式
通过给CSV格式归档表增加OSS_FILE_FILTER的table option来创建表的OSS_FILE_FILTER数据。OSS_FILE_FILTER格式如下:
OSS_FILE_FILTER = 'field_filter[,field_filter]'
field_filter := field_name[:filter_type]
filter_type := bloom各列类型均有默认的FILE_FILTER类型(数值和时间类型默认使用MIN/MAX统计过滤,字符串类型默认使用CHARACTOR MAP过滤),所有列类型均可通过指定FILE_FILTER为BLOOM类型使用布隆过滤器。
示例
归档冷存表时创建OSS_FILE_FITLER
手动归档表时创建OSS_FILE_FITLER
-- 表结构
CREATE TABLE `lineitem` (
`L_ORDERKEY` int(11) NOT NULL,
`L_PARTKEY` int(11) NOT NULL,
`L_SUPPKEY` int(11) NOT NULL,
`L_LINENUMBER` int(11) NOT NULL,
`L_QUANTITY` decimal(15,2) NOT NULL,
`L_EXTENDEDPRICE` decimal(15,2) NOT NULL,
`L_DISCOUNT` decimal(15,2) NOT NULL,
`L_TAX` decimal(15,2) NOT NULL,
`L_RETURNFLAG` char(1) COLLATE utf8_bin NOT NULL,
`L_LINESTATUS` char(1) COLLATE utf8_bin NOT NULL,
`L_SHIPDATE` date NOT NULL,
`L_COMMITDATE` date NOT NULL,
`L_RECEIPTDATE` date NOT NULL,
`L_SHIPINSTRUCT` char(25) COLLATE utf8_bin NOT NULL,
`L_SHIPMODE` char(10) COLLATE utf8_bin NOT NULL,
`L_COMMENT` varchar(44) COLLATE utf8_bin NOT NULL
) ENGINE = innodb;
-- 归档表同时在L_ORDERKEY、L_LINENUMBER、L_SHIPDATE列创建oss file filter
ALTER TABLE lineitem ENGINE = CSV STORAGE OSS
OSS_FILE_FILTER = 'L_ORDERKEY,L_LINENUMBER,L_SHIPDATE';已归档的表新增OSS_FILE_FITLER
对已经完成归档的表创建OSS_FILE_FITLER
-- 表结构
CREATE TABLE `lineitem` (
`L_ORDERKEY` int(11) NOT NULL,
`L_PARTKEY` int(11) NOT NULL,
`L_SUPPKEY` int(11) NOT NULL,
`L_LINENUMBER` int(11) NOT NULL,
`L_QUANTITY` decimal(15,2) NOT NULL,
`L_EXTENDEDPRICE` decimal(15,2) NOT NULL,
`L_DISCOUNT` decimal(15,2) NOT NULL,
`L_TAX` decimal(15,2) NOT NULL,
`L_RETURNFLAG` char(1) COLLATE utf8_bin NOT NULL,
`L_LINESTATUS` char(1) COLLATE utf8_bin NOT NULL,
`L_SHIPDATE` date NOT NULL,
`L_COMMITDATE` date NOT NULL,
`L_RECEIPTDATE` date NOT NULL,
`L_SHIPINSTRUCT` char(25) COLLATE utf8_bin NOT NULL,
`L_SHIPMODE` char(10) COLLATE utf8_bin NOT NULL,
`L_COMMENT` varchar(44) COLLATE utf8_bin NOT NULL
) ENGINE = CSV STORAGE OSS;
-- 在已经归档的表的L_ORDERKEY、L_LINENUMBER、L_SHIPDATE、L_SHIPINSTRUCT 列创建oss file filter,其中 L_SHIPINSTRUCT 列上是BLOOM
ALTER TABLE lineitem OSS_FILE_FILTER = 'L_ORDERKEY,L_LINENUMBER,L_SHIPDATE,L_SHIPINSTRUCT:BLOOM';使用OSS_FILE_FILTER
查询条件如果使用OSS_FILE_FILTER,将会被下推到CSV格式的OSS冷数据中。通过查询计划可以查看被下推到引擎的条件。
-- 表结构
CREATE TABLE `lineitem` (
`L_ORDERKEY` int(11) NOT NULL,
`L_PARTKEY` int(11) NOT NULL,
`L_SUPPKEY` int(11) NOT NULL,
`L_LINENUMBER` int(11) NOT NULL,
`L_QUANTITY` decimal(15,2) NOT NULL,
`L_EXTENDEDPRICE` decimal(15,2) NOT NULL,
`L_DISCOUNT` decimal(15,2) NOT NULL,
`L_TAX` decimal(15,2) NOT NULL,
`L_RETURNFLAG` char(1) COLLATE utf8_bin NOT NULL,
`L_LINESTATUS` char(1) COLLATE utf8_bin NOT NULL,
`L_SHIPDATE` date NOT NULL,
`L_COMMITDATE` date NOT NULL,
`L_RECEIPTDATE` date NOT NULL,
`L_SHIPINSTRUCT` char(25) COLLATE utf8_bin NOT NULL,
`L_SHIPMODE` char(10) COLLATE utf8_bin NOT NULL,
`L_COMMENT` varchar(44) COLLATE utf8_bin NOT NULL
) ENGINE = CSV STORAGE OSS OSS_FILE_FILTER = 'L_ORDERKEY,L_LINENUMBER,L_SHIPDATE';
-- 查询计划
explain select * from lineitem where l_orderkey=96;
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+----------+---------------------------------------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+----------+---------------------------------------------------------------------------------+
| 1 | SIMPLE | lineitem | NULL | ALL | NULL | NULL | NULL | NULL | 6001215 | 10.00 | Using where; With pushed engine condition (`test`.`lineitem`.`L_ORDERKEY` = 96) |
+----+-------------+----------+------------+------+---------------+------+---------+------+---------+----------+---------------------------------------------------------------------------------+
explain format = tree select * from lineitem where l_orderkey=96 \G
*************************** 1. row ***************************
EXPLAIN: -> Filter: (lineitem.L_ORDERKEY = 96) (cost=15010.00 rows=10000)
-> Table scan on lineitem, extra (oss_file_filter conditions: (lineitem.L_ORDERKEY = 96)) (cost=15010.00 rows=100000)
-- 执行SQL
select count(*) from lineitem where l_orderkey=96;