云数据库ClickHouse二级索引 - 最佳实践

本文介绍了阿里云数据库ClickHouse的二级索引功能,旨在优化海量数据分析中的多维度点查能力。文章详细阐述了ClickHouse在存储扫描、排序键、分区键、跳跃扫描、预查询等方面的性能优化技术,并探讨了二级索引的DDL语法、适用场景和特色功能。此外,文章还提供了实际业务场景中的案例,帮助读者理解如何利用这些技术提升OLAP查询性能。
摘要由CSDN通过智能技术生成

引言

阿里云数据库ClickHouse二级索引功能近日已正式发布上线,主要弥补了ClickHouse在海量数据分析场景下,多维度点查能力不足的短板。在以往服务用户的过程中,作者发现绝大部分用户对ClickHouse单表查询性能优化问题感到无从下手,借此机会,本文会先为大家展开介绍ClickHouse在单表分析查询性能优化上的几个方法,基本涵盖了OLAP领域存储层扫描加速的所有常用手段。在解决过各种各样业务场景下的性能优化问题后,作者发现目前ClickHouse在解决多维搜索问题上确实能力不足,一条点查常常浪费巨大的IO、CPU资源,于是云数据库ClickHouse自研了二级索引功能来彻底解决问题,本文会详细介绍二级索引的DDL语法、几个典型适用场景和特色功能。希望可以通过本文让大家对ClickHouse在OLAP场景下的能力有更深的理解,同时阐述清楚二级索引适用的搜索场景。

存储扫描性能优化

在介绍各类OLAP存储扫描性能优化技术之前,作者先在这里申明一个简单的代价模型和一些OLAP的背景知识。本文使用最简单的代价模型来计算OLAP存储扫描阶段的开销:磁盘扫描读取的数据量。在类似ClickHouse这样纯列式的存储和计算引擎中,数据的压缩、计算、流转都是以列块为单位按列进行的。在ClickHouse中,只能对数据列以块为单位进行定位读取,虽然用户的查询是按照uid查询确定的某一条记录,但是从磁盘读取的数据量会被放大成块大小 * 列数。本文中不考虑数据缓存(BlockCache / PageCache)这些优化因素,因为Cache可以达到的优化效果不是稳定的。

排序键优化-跳跃扫描

排序键是ClickHouse最主要依赖的存储扫描加速技术,它的含义是让存储层每个DataPart里的数据按照排序键进行严格有序存储。正是这种有序存储的模式,构成了ClickHouse "跳跃"扫描的基础和重复数据高压缩比的能力(对于ClickHouse的MergeTree存储结构不熟悉的同学可以参考往期文章《ClickHouse内核分析-MergeTree的存储结构和查询加速》)。

CREATE TABLE order_info
(
    `oid`   UInt64,                     --订单ID
    `buyer_nick`    String,     --买家ID
    `seller_nick`   String,     --店铺ID
    `payment`   Decimal64(4), --订单金额
    `order_status`  UInt8,         --订单状态
    ...
    `gmt_order_create`  DateTime, --下单时间
    `gmt_order_pay` DateTime,         --付款时间
    `gmt_update_time` DateTime,     --记录变更时间
    INDEX oid_idx (oid) TYPE minmax GRANULARITY 32
)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(gmt_order_create)         --以天为单位分区
ORDER BY (seller_nick, gmt_order_create, oid) --排序键
PRIMARY KEY (seller_nick, gmt_order_create)     --主键
SETTINGS index_granularity = 8192;

以一个简单的订单业务场景为例(表结构如上),order by定义了数据文件中的记录会按照店铺ID , 下单时间以及订单号组合排序键进行绝对有序存储,而primary key和index_granularity两者则定义了排序键上的索引结构长什么样子,ClickHouse为每一个有序的数据文件构造了一个"跳跃数组"作为索引,这个"跳跃数组"中的记录是从原数据中按一定间隔抽取出来得到的(简化理解就是每隔index_granularity抽取一行记录),同时只保留primary key定义里的seller_nick, gmt_order_create两个前缀列。如下图所示,有了这个全内存的"跳跃数组"作为索引,优化器可以快速排除掉和查询无关的行号区间,大大减少磁盘扫描的数据量。至于为何不把oid列放到primary key中,读者可以仔细思考一下原因,和index_granularity设定值大小也有关。

作者碰到过很多用户在把mysql的binlog数据迁移到ClickHouse上做分析时,照搬照抄mysql上的主键定义,导致ClickHouse的排序键索引基本没有发挥出任何作用,查询性能主要就是靠ClickHouse牛逼的数据并行扫描能力和高效的列式计算引擎在硬抗,这也从侧面反应出ClickHouse在OLAP场景下的绝对性能优势,没有任何索引依旧可以很快。业务系统中的mysql主要侧重单条记录的事务更新,主键是可以简单明了定义成oid,但是在OLAP场景下查询都需要做大数据量的扫描分析,ClickHouse需要用排序键索引来进行"跳跃"扫描,用户建表时应尽量把业务记录生命

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值