暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PolarDB MySQL冷存查询加速之OSS数据筛选

原创 Moss 2024-09-27
128
背景

PolarDB MySQL提供OSS冷数据归档功能,支持将历史冷数据转存至低成本的OSS上存储,以降低数据存储成本。针对OSS上归档的冷数据,业务层面会存在离线全量的BI报表统计分析以类ADHOC等在线业务的复杂查询。

PolarDB for MySQL在优化冷数据查询性能方面,聚焦于两项核心技术策略:OSS数据筛选机制与OSS冷数据并行处理技术。

本文将先介绍PolarDB MySQL加速OSS数据筛选机制的实现,OSS数据筛选机制通过利用高度针对性的列属性预处理,实现对数据对象的智能过滤。这一策略能够显著缩减数据扫描范围,避免不必要的时间消耗于无关数据的检索上,从而大幅提升查询效率与系统响应速度。


OSS_FILE_FILTER 查询优化

PolarDB MySQL冷数据查询功能已经支持了OSS文件筛选 OSS FILE FILTER 功能,该功能通过利用查询条件预前锁定数据存储位置,实现了数据检索策略的优化升级。相较于传统的并行查询方法,OSS FILE FILTER 展现出更高的资源效率,在具备有利筛选条件的场景下,其查询性能的提升效果尤为显著,这不仅归功于减少了不必要的数据扫描,还有效提升了处理速度与系统响应能力。以下我们进行详细介绍。

使用方法:

这里以经典的 lineitem 表作为分析案例,介绍如何使用 OSS FILE FILTER 加速查询。我们提前生成了一个大约 10G 的 TPCH lineitem 标准数据集,表定义如下:

mysql> show create table lineitem \G
*************************** 1. row ***************************
       Table: lineitem
Create Table: 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(10,2) NOT NULL,
  `l_extendedprice` decimal(10,2) NOT NULL,
  `l_discount` decimal(10,2) NOT NULL,
  `l_tax` decimal(10,2) NOT NULL,
  `l_returnflag` char(1) NOT NULL,
  `l_linestatus` char(1) NOT NULL,
  `l_shipDATE` date NOT NULL,
  `l_commitDATE` date NOT NULL,
  `l_receiptDATE` date NOT NULL,
  `l_shipinstruct` char(25) NOT NULL,
  `l_shipmode` char(10) NOT NULL,
  `l_comment` varchar(44) NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ CONNECTION='default_oss_server'
1 row in set (0.01 sec)
复制

可以看到,当前表已经开启了 OSS META,这是冷数据 OSS File Filter 的前提,我们以 Q6 为例,查看其执行计划:

首先,打开 OSS File Filter 的开关:

SET csv_oss_file_filter = ON;
复制


执行计划为:

mysql> explain select
    ->     sum(l_extendedprice * l_discount) as revenue
    -> from
    ->     lineitem
    -> where
    ->     l_shipdate >= date '1994-01-01'
    ->     and l_shipdate < date '1994-01-01' + interval '1' year
    ->     and l_discount between 0.06 - 0.01 and 0.06 + 0.01
    ->     and l_quantity < 24;
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows     | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+-------------+
|  1 | SIMPLE      | lineitem | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 59986051 |     0.41 | Using where |
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
复制


实际执行时间大约为 5min

mysql> select
    ->     sum(l_extendedprice * l_discount) as revenue
    -> from
    ->     lineitem
    -> where
    ->     l_shipdate >= date '1994-01-01'
    ->     and l_shipdate < date '1994-01-01' + interval '1' year
    ->     and l_discount between 0.06 - 0.01 and 0.06 + 0.01
    ->     and l_quantity < 24;
+-----------------+
| revenue         |
+-----------------+
| 1230113636.0101 |
+-----------------+
1 row in set (5 min 11.25 sec)
复制


而 Q6 上主要用了 l_shipdate ,l_discount ,l_quantity Filter,我们在这几列上增加 OSS FILE FILTER,语法为:

mysql> ALTER TABLE lineitem OSS_FILE_FILTER = 'l_shipdate,l_quantity,l_discount';
复制


执行完成后,可以看到表定义变为:

mysql> show create table lineitem \G
*************************** 1. row ***************************
       Table: lineitem
Create Table: 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(10,2) NOT NULL,
  `l_extendedprice` decimal(10,2) NOT NULL,
  `l_discount` decimal(10,2) NOT NULL,
  `l_tax` decimal(10,2) NOT NULL,
  `l_returnflag` char(1) NOT NULL,
  `l_linestatus` char(1) NOT NULL,
  `l_shipDATE` date NOT NULL,
  `l_commitDATE` date NOT NULL,
  `l_receiptDATE` date NOT NULL,
  `l_shipinstruct` char(25) NOT NULL,
  `l_shipmode` char(10) NOT NULL,
  `l_comment` varchar(44) NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ /*!99990 800020223 OSS_FILE_FILTER='l_shipdate,l_quantity,l_discount' */ CONNECTION='default_oss_server'
1 row in set (0.00 sec)
复制


此时,再执行 Q6,explain 看了看到使用了查询加速功能,同时执行时间缩短了很多。

mysql> explain select
    ->     sum(l_extendedprice * l_discount) as revenue
    -> from
    ->     lineitem
    -> where
    ->     l_shipdate >= date '1994-01-01'
    ->     and l_shipdate < date '1994-01-01' + interval '1' year
    ->     and l_discount between 0.06 - 0.01 and 0.06 + 0.01
    ->     and l_quantity < 24 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: lineitem
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 59986051
     filtered: 0.41
        Extra: Using where; With pushed engine condition ((`multiply`.`lineitem`.`l_shipDATE` >= DATE'1994-01-01') and (`multiply`.`lineitem`.`l_shipDATE` < <cache>((DATE'1994-01-01' + interval '1' year))) and (`multiply`.`lineitem`.`l_discount` between <cache>((0.06 - 0.01)) and <cache>((0.06 + 0.01))) and (`multiply`.`lineitem`.`l_quantity` < 24.00))
1 row in set, 1 warning (0.01 sec)

mysql> select
    ->     sum(l_extendedprice * l_discount) as revenue
    -> from
    ->     lineitem
    -> where
    ->     l_shipdate >= date '1994-01-01'
    ->     and l_shipdate < date '1994-01-01' + interval '1' year
    ->     and l_discount between 0.06 - 0.01 and 0.06 + 0.01
    ->     and l_quantity < 24;
+-----------------+
| revenue         |
+-----------------+
| 1230113636.0101 |
+-----------------+
1 row in set (3 min 59.63 sec)
复制


由于 Q6 的查询条件筛选率并不高,如果是在 l_orderkey 上做等值查询,查询时间可以直接缩短到秒级。首先,在 l_orderkey 上增加 OSS FILE FILTER

mysql> ALTER TABLE lineitem OSS_FILE_FILTER = 'l_orderkey,l_shipdate,l_quantity,l_discount';
复制


随后执行一个等值查询:

mysql>   select * from lineitem where l_orderkey = 70;
+------------+-----------+-----------+--------------+------------+-----------------+------------+-------+--------------+--------------+------------+--------------+---------------+------------------+------------+-----------------------------------------+
| l_orderkey | l_partkey | l_suppkey | l_linenumber | l_quantity | l_extendedprice | l_discount | l_tax | l_returnflag | l_linestatus | l_shipDATE | l_commitDATE | l_receiptDATE | l_shipinstruct   | l_shipmode | l_comment                               |
+------------+-----------+-----------+--------------+------------+-----------------+------------+-------+--------------+--------------+------------+--------------+---------------+------------------+------------+-----------------------------------------+
|         70 |    641279 |     91292 |            1 |       8.00 |         9761.92 |       0.03 |  0.08 | R            | F            | 1994-01-12 | 1994-02-27   | 1994-01-14    | TAKE BACK RETURN | FOB        | ggle. carefully pending dependenc       |
|         70 |   1961552 |     11591 |            2 |      13.00 |        20974.98 |       0.06 |  0.06 | A            | F            | 1994-03-03 | 1994-02-13   | 1994-03-26    | COLLECT COD      | AIR        | lyly special packag                     |
|         70 |   1798088 |     73140 |            3 |       1.00 |         1186.00 |       0.03 |  0.05 | R            | F            | 1994-01-26 | 1994-03-05   | 1994-01-28    | TAKE BACK RETURN | RAIL       | quickly. fluffily unusual theodolites c |
|         70 |    457332 |      7341 |            4 |      11.00 |        14182.41 |       0.01 |  0.05 | A            | F            | 1994-03-17 | 1994-03-17   | 1994-03-27    | NONE             | MAIL       | alongside of the deposits. fur          |
|         70 |    371307 |     21314 |            5 |      37.00 |        50996.73 |       0.09 |  0.04 | R            | F            | 1994-02-13 | 1994-03-16   | 1994-02-21    | COLLECT COD      | MAIL       | n accounts are. q                       |
|         70 |    556542 |     31558 |            6 |      19.00 |        30371.88 |       0.06 |  0.03 | A            | F            | 1994-01-26 | 1994-02-17   | 1994-02-06    | TAKE BACK RETURN | SHIP       |  packages wake pending accounts.        |
+------------+-----------+-----------+--------------+------------+-----------------+------------+-------+--------------+--------------+------------+--------------+---------------+------------------+------------+-----------------------------------------+
6 rows in set (2.13 sec)
复制

性能测试

OSS_FILE_FILTER 技术的核心机制在于预计算并存储表内各数据块的统计概况,从而在查询过程中依据这些信息迅速锁定目标数据块的位置。此机制的性能优化效果显著依赖于 File Filter 的过滤效率(Selectivity),即返回结果占总数据量的比例。最理想的应用场景是对主键(primary key)或唯一键(unique key)执行 FILE FILTER,因为这类键值具有高度区分度,能极大提升过滤效率。
我们在 TB 量级的 TPCH 测试数据集上,对 OSS_FILE_FILTER 的筛选效率与查询响应时间之间的关系进行了分析。结果如下图所示,可以观察到,当查询操作基于主键或唯一键执行时,意味着 OSS_FILE_FILTER 能够展现出极高的过滤效能。这种高度针对性的查询策略,几乎无一例外地确保了查询结果在秒级内的迅速反馈。相比之下,若采取全表扫描的方式进行数据检索,则面临着迥异的情境。全表扫描因其遍历整个数据集的特性,导致查询成本急剧增加,几乎达到了不可承受的程度,特别是在如此大规模的数据体量下。



总结
通过PolarDB MySQ冷数据OSS文件筛选功能,允许用户通过指定列来预筛选数据,减少不必要的数据扫描,提高查询效率。在启用该功能后,查询性能尤其是在具有高选择性的条件查询下得到了显著提升。例如,在TPC-H的lineitem表上,通过设置OSS_FILE_FILTER,针对特定列的查询时间从几分钟缩短到了几秒钟。
最后修改时间:2024-09-27 14:16:01
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论