clickhouse的稀疏索引

这篇具有很好参考价值的文章主要介绍了clickhouse的稀疏索引。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

clickhouse官网

稀疏索引

在使用primary key的时候指定的key必须是在order by多个字段中排在前面

CREATE TABLE hits_UserID_URL
(
`UserID` UInt32,
`URL` String,
`EventTime` DateTime
)
ENGINE = MergeTree
PRIMARY KEY (UserID, URL)
ORDER BY (UserID, URL, EventTime)
SETTINGS index_granularity = 8192, index_granularity_bytes = 0;


-- 查看索引的行数marks SELECT part_type, path, formatReadableQuantity(rows) AS rows, formatReadableSize(data_uncompressed_bytes) AS data_uncompressed_bytes, formatReadableSize(data_compressed_bytes) AS data_compressed_bytes, formatReadableSize(primary_key_bytes_in_memory) AS primary_key_bytes_in_memory, marks, formatReadableSize(bytes_on_disk) AS bytes_on_disk FROM system.parts WHERE (table = 'hits_UserID_URL') AND (active = 1) FORMAT Vertical; part_type: Wide path: ./store/d9f/d9f36a1a-d2e6-46d4-8fb5-ffe9ad0d5aed/all_1_9_2/ rows: 8.87 million data_uncompressed_bytes: 733.28 MiB data_compressed_bytes: 206.94 MiB primary_key_bytes_in_memory: 96.93 KiB marks: 1083 bytes_on_disk: 207.07 MiB 1 rows in set. Elapsed: 0.003 sec.

  

1、在介绍索引之前先介绍下clickhouse存储数据的方式

  在clickhouse中数据按照行列是存储在bin文件下的,也就是每一个列有一个文件夹。

  在下图中显示每隔8192行或者是10M生成一个granule(颗粒),我更喜欢叫做块,块内有序。

clickhouse的稀疏索引

 

2、稀疏索引工作原理

每一个块的第一条就会存储在索引中,这个索引存储在.idx文件中,然后被读入内存

clickhouse的稀疏索引

 

SELECT URL, count(URL) AS Count
FROM hits_UserID_URL
WHERE UserID = 749927693
GROUP BY URL
ORDER BY Count DESC
LIMIT 10;

结果:

┌─URL────────────────────────────┬─Count─┐
│ http://auto.ru/chatay-barana.. │ 170 │
│ http://auto.ru/chatay-id=371...│ 52 │
│ http://public_search │ 45 │
│ http://kovrik-medvedevushku-...│ 36 │
│ http://forumal │ 33 │
│ http://korablitz.ru/L_1OFFER...│ 14 │
│ http://auto.ru/chatay-id=371...│ 14 │
│ http://auto.ru/chatay-john-D...│ 13 │
│ http://auto.ru/chatay-john-D...│ 10 │
│ http://wot/html?page/23600_m...│ 9 │
└────────────────────────────────┴───────┘

10 rows in set. Elapsed: 0.005 sec.
Processed 8.19 thousand rows,
740.18 KB (1.53 million rows/s., 138.59 MB/s.)

ClickHouse客户端的输出现在显示,只有8190行流到ClickHouse,而不是进行完整的表扫描。执行计划:

┌─explain───────────────────────────────────────────────────────────────────────────────┐
│ Expression (Projection) │
│ Limit (preliminary LIMIT (without OFFSET)) │
│ Sorting (Sorting for ORDER BY) │
│ Expression (Before ORDER BY) │
│ Aggregating │
│ Expression (Before GROUP BY) │
│ Filter (WHERE) │
│ SettingQuotaAndLimits (Set limits and quota after reading from storage) │
│ ReadFromMergeTree │
│ Indexes: │
│ PrimaryKey │
│ Keys: │
│ UserID │
│ Condition: (UserID in [749927693, 749927693]) │
│ Parts: 1/1 │
│ Granules: 1/1083 │
└───────────────────────────────────────────────────────────────────────────────────────┘

16 rows in set. Elapsed: 0.003 sec.

稀疏索引第一步是先通过二分查找快速寻找对应的块,第二步把这个块的数据解压,并寻找匹配的行数据

3、mrk文件为idx和bin架起来桥梁

  mrk文件记录了索引,以及它对应的块的真实物理地址(block_offset),和解压后的位置(granule_offset)

clickhouse的稀疏索引

  索引通过block_offset锁定块,然后解压并加载到内存中,再通过granule_offset寻找数据的位置

 

 

clickhouse的稀疏索引

 4、在使用多个索引的时候第二个键列作为筛选条件呢

      第一个键列是直接使用快速二分查找,那直接用第二个键列呢

SELECT UserID, count(UserID) AS Count
FROM hits_UserID_URL
WHERE URL = 'http://public_search'
GROUP BY UserID
ORDER BY Count DESC
LIMIT 10;


┌─────UserID─┬─Count─┐
│ 2459550954 │  3741 │
│ 1084649151 │  2484 │
│  723361875 │   729 │
│ 3087145896 │   695 │
│ 2754931092 │   672 │
│ 1509037307 │   582 │
│ 3085460200 │   573 │
│ 2454360090 │   556 │
│ 3884990840 │   539 │
│  765730816 │   536 │
└────────────┴───────┘

10 rows in set. Elapsed: 0.086 sec.
Processed 8.81 million rows,
799.69 MB (102.11 million rows/s., 9.27 GB/s.)

 

-- trace_logging 
...Executor): Key condition: (column 1 in ['http://public_search', 'http://public_search']) ...Executor): Used generic exclusion search over index for part all_1_9_2 with 1537 steps ...Executor): Selected 1/1 parts by partition key, 1 parts by primary key, 1076/1083 marks by primary key, 1076 marks to read from 5 ranges ...Executor): Reading approx. 8814592 rows with 10 streams

  从结果可以看到url是第二键列,用它作为条件过滤,在数据量887万行中读取了881万行,几乎是全表扫描。为什么呢?

  在 trace_logging中我们可以看到总共1083个块,但是1076个块中被认为可能有 url=http://public_search',但是实际上只有39个有

  好像我们可以得出在符合主键 (UserID, URL)中对UserID确实有作用,但是对于URL就等同失效了

但是是真的是这样吗?其实这个和第一个键的占比很关键。

举个例子寻找URL=W3的 

  数据是先按照UserID排序后再按照URL排序,在UserID值比较少的时候,一个userID有很多条mark数据,因此就可以筛掉很多块。例如下图

  因为userID一样,那么就可以直接比较URL,在mark0是W1而且mark1是W2,那么就可以直接认为mark0不可能含有W3,mark0就过掉了,mark2的URL比W3大,那么mark2以上的也不可能包含w3,那么只需要把mark1对应的数据进行寻找。

   那么这个索引建立还是很有作用的

clickhouse的稀疏索引

 但是如果UserID很多,那就很等同失效

例如下图:

U1、U2、U3也可能有W3,这样子的话只能全表扫描了

clickhouse的稀疏索引

 总结:

在多个索引时,使用第一个作为筛选条件是最好的,但是如果使用第二个的话,建议是在前置键列的基数较低(er)时最有效(也就是种类很少的时候,例如UserID很少)文章来源地址https://www.toymoban.com/news/detail-736828.html

到了这里,关于clickhouse的稀疏索引的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 优化索引粒度参数提升ClickHouse查询性能

    当对高基数列进行过滤查询时,总是希望尽可能跳过更多的行。否则需要处理更多数据、需要更多资源。ClickHouse缺省在MergeTree表读取8192行数据块,但我们可以在创建表时调整该 index_granularity 参数。本文通过示例说明如何调整该参数优化查询性能。 下面示例,创建表并插入

    2024年02月11日
    浏览(45)
  • 《算法工程师带你去》读书笔记 什么是稀疏向量(向量的稀疏表示)

    对数据进行预处理时,一般需要对类别型特征进行编码: 序号编码 独热编码 二进制编码 其中独热编码用的是最多的。但是当类别数十分巨大时,独热编码是一个非常稀疏的向量,只有一个值不为0,其他值均为0。可以使用向量的稀疏表示来大大的 节省空间 ,并且目前大多

    2024年02月03日
    浏览(38)
  • 【数据结构】数组(稀疏矩阵、特殊矩阵压缩、矩阵存储、稀疏矩阵的快速转置、十字链表)

    前几期期链接: 【数据结构】栈与队列的概念和基本操作代码实现 【数据结构】树与二叉树的概念与基本操作代码实现 k维数组的定义: k 维数组 D = { a j 1 , j 2 , . . . , j k } k维数组D={ a_{j_1, j_2, ..., j_k} } k 维数组 D = { a j 1 ​ , j 2 ​ , ... , j k ​ ​ } k 0 称为数组的维数,

    2024年04月09日
    浏览(140)
  • 【数据结构】数组和字符串(五):特殊矩阵的压缩存储:稀疏矩阵——压缩稀疏行(CSR)

    【数据结构】数组和字符串(一):矩阵的数组表示   矩阵是以按行优先次序将所有矩阵元素存放在一个一维数组中。但是对于特殊矩阵,如对称矩阵、三角矩阵、对角矩阵和稀疏矩阵等, 如果用这种方式存储,会出现大量存储空间存放重复信息或零元素的情况,这样会造

    2024年02月05日
    浏览(54)
  • 【华为OD统一考试B卷 | 100分】矩阵稀疏扫描、 稀疏矩阵(C++ Java JavaScript Python)

    在线OJ 已购买本专栏用户,请私信博主开通账号,在线刷题!!! 运行出现 Runtime Error 0Aborted,请忽略 华为OD统一考试A卷+B卷 新题库说明 2023年5月份,华为官方已经将的 2022/0223Q(1/2/3/4)统一修改为OD统一考试(A卷)和OD统一考试(B卷)。 你收到的链接上面会标注A卷还是B卷。

    2024年02月09日
    浏览(47)
  • sparse conv稀疏卷积

     很好的教程,感谢作者的分享 通俗易懂的解释Sparse Convolution过程 - 知乎 稀疏卷积和普通卷积的区别 spconv和普通卷积没有区别,最重要的区别在于卷积的数据的存储方式和计算方法,这种计算方法可以增加计算稀疏点云的效率,其他的都是完全相同的(但SubMConv3d还是稍微有点

    2024年02月11日
    浏览(39)
  • Scipy 高级教程——稀疏矩阵

    Scipy 提供了处理稀疏矩阵的工具,这对于处理大规模数据集中的稀疏数据是非常有效的。本篇博客将深入介绍 Scipy 中的稀疏矩阵功能,并通过实例演示如何应用这些工具。 1. 稀疏矩阵的表示 在 Scipy 中,稀疏矩阵可以使用 scipy.sparse 模块进行表示。常用的稀疏矩阵类型有 cs

    2024年01月17日
    浏览(37)
  • 13、稀疏矩阵

    目录 一、稀疏矩阵的生成 1.利用sparse函数建立一般的稀疏矩阵 2.利用特定函数建立稀疏矩阵 二、稀疏矩阵的运算 1.利用sparse函数建立一般的稀疏矩阵 稀疏矩阵指令的调用格式: 示例1 :输入一个稀疏矩阵 运行结果: 此外, sparse函数 还可以将一个满矩阵转换成一个稀疏矩阵

    2024年02月07日
    浏览(49)
  • 【scipy 基础】--稀疏矩阵

    稀疏矩阵 是一种特殊的矩阵,其非零元素数目远远少于零元素数目,并且非零元素分布没有规律。 这种矩阵在实际应用中经常出现,例如在物理学、图形学和网络通信等领域。 稀疏矩阵 其实也可以和一般的矩阵一样处理,之所以要把它区分开来进行特殊处理,是因为: 一

    2024年02月05日
    浏览(40)
  • 数据结构——稀疏矩阵

    在矩阵中,若数据为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反的叫做稠密矩阵。 将棋盘看作一个二维数组,在棋子落盘时,要记录该棋子落下的坐标,其他坐标的值不做记录,默认为0。由于记录很多无意义的数据

    2024年02月03日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包