TIDB HTAP TIFLASH引擎的使用

1.TIDB HTAP 

HTAP 是 Hybrid Transactional / Analytical Processing 的缩写。传统意义上,数据库往往专为交易或者分析场景设计,
因而数据平台往往需要被切分为 Transactional Processing 和 Analytical Processing 两个部分,
而数据需要从交易库复制到分析型数据库以便快速响应分析查询。而 TiDB 数据库则可以同时承担交易和分析两种职能,
这大大简化了数据平台的建设,也能让用户使用更新鲜的数据进行分析。

在 TiDB 当中,同时拥有面向在线事务处理的行存储引擎 TiKV 与面向实时分析场景的列存储引擎 TiFlash 两套存储引擎。
数据在行存 (Row-Store) 与列存 (Columnar-Store) 同时存在,自动同步,保持强一致性。行存为在线事务处理 OLTP 提供优化,
列存则为在线分析处理 OLAP 提供性能优化。


数据准备
在开始之前,你可以通过 tiup demo 命令导入更加大量的示例数据,例如:

tiup demo bookshop prepare --users=200000 --books=500000 --authors=100000 --ratings=1000000 --orders=1000000 --host 127.0.0.1 --port 4000 --drop-tables

窗口函数
在使用数据库时,除了希望它能够存储想要记录的数据,能够实现诸如下单买书、给书籍评分等业务功能外,
可能还需要对已有的数据进行分析,以便根据数据作出进一步的运营和决策。
在单表读取章节当中,已经介绍了如何使用聚合查询来分析数据的整体情况,在更为复杂的使用场景下,
你可能希望多个聚合查询的结果汇总在一个查询当中。例如:你想要对某一本书的订单量的历史趋势有所了解,
就需要在每个月都对所有订单数据进行一次聚合求 sum,然后将 sum 结果汇总在一起才能够得到历史的趋势变化数据。
为了方便用户进行此类分析,TiDB 从 3.0 版本开始便支持了窗口函数功能,窗口函数为每一行数据提供了跨行数据访问的能力,
不同于常规的聚合查询,窗口函数在对数据行进行聚合时不会导致结果集被合并成单行数据。

与聚合函数类似,窗口函数在使用时也需要搭配一套固定的语法:

WITH orders_group_by_month AS (
  SELECT DATE_FORMAT(ordered_at, '%Y-%c') AS month, COUNT(*) AS orders
  FROM orders
  WHERE book_id = 3461722937
  GROUP BY 1
)
SELECT
month,
SUM(orders) OVER(ORDER BY month ASC) as acc
FROM orders_group_by_month
ORDER BY month ASC;

#sum() 函数会在 OVER 子句当中通过 ORDER BY 子句指定的排序方式按顺序对数据进行累加,

#PARTITION BY 子句
WITH orders_group_by_month AS (
    SELECT
        b.type AS book_type,
        DATE_FORMAT(ordered_at, '%Y-%c') AS month,
        COUNT(*) AS orders
    FROM orders o
    LEFT JOIN books b ON o.book_id = b.id
    WHERE b.type IS NOT NULL
    GROUP BY book_type, month
), acc AS (
    SELECT
        book_type,
        month,
        SUM(orders) OVER(PARTITION BY book_type ORDER BY book_type, month ASC) as acc
    FROM orders_group_by_month
    ORDER BY book_type, month ASC
)
SELECT * FROM acc;

#非聚合窗口函数
除此之外,TiDB 还提供了一些非聚合的窗口函数,可以借助这些函数实现更加丰富分析查询。
例如,在前面的分页查询章节当中,已经介绍了如何巧妙地利用 row_number() 函数实现高效的分页批处理能力

混合负载
当将 TiDB 应用于在线实时分析处理的混合负载场景时,开发人员只需要提供一个入口,TiDB 将自动根据业务类型选择不同的处理引擎。

开启列存副本
TiDB 默认使用的存储引擎 TiKV 是行存的,你可以通过阅读开启 HTAP 能力章节,在进行后续步骤前,
先通过如下 SQL 对 books 与 orders 表添加 TiFlash 列存副本:

ALTER TABLE books SET TIFLASH REPLICA 1;
ALTER TABLE orders SET TIFLASH REPLICA 1;
通过执行下面的 SQL 语句可以查看到 TiDB 创建列存副本的进度:

SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = 'bookshop' and TABLE_NAME = 'books';
SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = 'bookshop' and TABLE_NAME = 'orders';
当 PROGRESS 列为 1 时表示同步进度完成度达到 100%,AVAILABLE 列为 1 表示副本当前可用。

副本添加完成之后,你可以通过使用 EXPLAIN 语句查看上面窗口函数示例 SQL 的执行计划。
你会发现执行计划当中已经出现了 cop[tiflash] 字样,说明 TiFlash 引擎已经开始发挥作用了。
 
通过对比前后两次的执行结果,你会发现使用 TiFlash 处理有查询速度有了较为明显的提升(当数据量更大时,提升会更为显著)。
这是因为在使用窗口函数时往往需要对某些列的数据进行全表扫描,相比行存的 TiKV,
列存的 TiFlash 更加适合来处理这类分析型任务的负载。而对于 TiKV 来说,如果能够通过主键或索引快速地将所要查询的行数减少,
往往查询速度也会非常快,而且所消耗的资源一般相对 TiFlash 而言会更少。

指定查询引擎
尽管 TiDB 会使用基于成本的优化器(CBO)自动地根据代价估算选择是否使用 TiFlash 副本。但是在实际使用当中,
如果你非常确定查询的类型,推荐你使用 Optimizer Hints 明确的指定查询所使用的执行引擎,避免因为优化器的优化结果不同,
导致应用程序性能出现波动。

你可以像下面的 SQL 一样在 SELECT 语句中通过 Hint /*+ read_from_storage(engine_name[table_name]) */ 
指定查询时需要使用的查询引擎。

注意
如果你的表使用了别名,你应该将 Hints 当中的 table_name 替代为 alias_name,否则 Hints 会失效。
另外,对公共表表达式[CTE]设置 read_from_storage Hint 是不起作用的。

#如下SQL的HINT /*+ read_from_storage(tikv[o]) */ 将不会起作用。
WITH orders_group_by_month AS (
    SELECT
        /*+ read_from_storage(tikv[o]) */
        b.type AS book_type,
        DATE_FORMAT(ordered_at, '%Y-%c') AS month,
        COUNT(*) AS orders
    FROM orders o
    LEFT JOIN books b ON o.book_id = b.id
    WHERE b.type IS NOT NULL
    GROUP BY book_type, month
), acc AS (
    SELECT
        book_type,
        month,
        SUM(orders) OVER(PARTITION BY book_type ORDER BY book_type, month ASC) as acc
    FROM orders_group_by_month mo
    ORDER BY book_type, month ASC
)
SELECT * FROM acc;

如果你通过 EXPLAIN 语句查看上面 SQL 的执行计划,你会发现 task 列中会同时出现 cop[tiflash] 和 cop[tikv],
这意味着 TiDB 在处理这个查询的时候会同时调度行存查询引擎和列存查询引擎来完成查询任务。
需要指出的是,因为 tiflash 和 tikv 存储引擎通常属于不同的计算节点,所以两种查询类型互相之间不受影响。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值