00:00
好,那么接下来我们来聊一聊这个爬提升败,嗯,咱们前面简单演示了对吧,有三个可以用的功能,一个分区,一个组件,一个order by,其中呢,组件它不是。具有唯一唯一性对吧,那关于这个爬丁生拜,我们这个这三个东西我们可以在官网上找到啊,我们点开引擎表引擎,然后呢一个。合并数引擎啊,点开那其实。这里我们看看它的一个官方语法。你看看这里。这两个被什么包裹了?是不是一个中括号啊?那么可想而知,中括号是什么可选的,也就是说他们不是必须的对吧?但是有一个东西居然是必须的,大家可能以为是主见,对吧,并不是,它是什么呢?
01:00
Order by字段是必须的。Order by是必须的,那后面这个所谓的组件,它并不是必须的啊,那其实大家往下拉一拉,它每一个有展开解释,你看order by。排序的key爬犁申败。分区的分区键,它是什么?Option对吧,可选的,那包括咱们的主件,它也是什么可选。那其他的还有一些功能对吧,可以设置一些参数值啊,还可以设置一个TTRTTR,咱们后面一点来讲,还有这个采样,采样咱们高级也有介绍啊。大概就这样子,那我们来看一看,详细聊一聊啊,他BY这个分区啊,首先它的一个作用,我相信大家应该不陌生呗,咱们的have里面是不是也会做一个分区啊。对吧,那它主要的目的是什么?咱们help的目的是不是避免填表扫描啊,对吧,你在查询语句里面V过滤条件加一个分区字段的取值。
02:04
那就可以避免咱们全表扫描,优化一个查询速度,那么大家想一想。为什么have它可以避免全秒扫描呢?为什么我指定的分区的值,比如说是按天我指定为某一天。他就不会扫描其他的T的数据了吗?它是怎么实现的?大家可以思考思考,对比一下它是不是?大家想想hi的分区怎么实现呢?分什么目录呗。对吧,分目录啊,就像你钱多的存不下了,你有十个亿的现金啊,你是不是分了好几个房间去放啊。对吧,那你这个时候。你你你是不是只打开提供一个房间,你是不是过滤说某个房间编号,比如说12345,你说我只想用三号房间的。钱你是不是去三号房间拿就行了,你不用进其他房间,对吧,对吧,类似的一个道理,分目录,那咱们click house呢,一样的,它也是做了一个区分。
03:11
啊,分区啊,它也是分什么目录,但区别在哪呢?Hi的目录是在哪里啊?它是在HDFS对不对,那咱们click house是在什么本地磁盘。本地磁盘啊,一会儿咱们去瞅一瞅啊,那如果咱们不写分区呢,也就是说我电表的时候,我们说了可选对吧?不且呢,那他只会用一个分区,什么样的分区呢,叫做哦。对吧。它的目录名就是一个哦。然后呢,都在里面,所有数据都在里面啊,那它的分区目录里面有一些东西,它里面有什么呢?数据文件,索引文件,还有一些其他的东西。当然它是按分区来区分的,对吧,一个分区一个目录,一个分区一个目录里面呢,都有数据啊,所以呢,还有其他的啊校验啊等等一会咱们去看一看啊,我们先整体把这些聊一聊,那并行。
04:13
咱们说了它单个查询是不是可以多线程同时执行啊,那你想想每个线程之间怎么划分呢?你是不是得区分开啊,说各自处理一部分呢,那这个部分是怎么划分的,如果是分区,那么就是一个分区。一个线程呗,比如说我一共十个分区,我用十个线程,那就是每个线程都处理一个分区的数据,对吧,他这么来的,那咱们在实际生产应用中啊,通常按照什么按天来分区啊,这是咱们这也是官方比较推荐的一种分区方式,按天来分区,因为你少了没必要多了呢。反而会造成麻烦对吧?好,那还有一个什么数据写入与分区合并,咱们一会再来聊,先把前面这几个基本信息咱们来玩一玩啊呃,也不是玩一玩,咱们来进一步的理解,咱们不是说了。
05:09
它在存储的时候是咱们的什么呀。本地支行呗,那还记得路径吗?路径默认是什么哇,Live click house对吧,应该没权限,那我切一下root用户啊。好,我们再进来瓦利利house来看一下,这其实咱们之前看过对吧,我们说这,呃,对于咱们来讲,比较关注的应该是这个跟这这两个东西,一个是数据存储的路径,一个是表的结构信息在这里。啊,那我们先来看一下这个原数据呗,你看看里面有什么什么文件呢。是什么点circle啊,对不对,就建表语句呗,那其他另外这个所谓的default system是什么意思呢?还有这个文件名是不库名啊来我们在这,呃,客户端里面show data basis。
06:08
是不是就是库明啊,对吧,跟help有点类似,这是一个路径,对吧,比如说咱们进入default看一眼他有什么,他们这两个东西是啥,很熟呗,是表明啊,那这个点搜搜文件,这就是所谓的元数据,来我show tables是不是两张表。两张表呗,来,那你再看看它的circle里面写了啥啊,Vimt你看是不是超简单,是不是超简单难,这个是不是就是咱们的建表语句,只不过他给我们加了一些东西,Attach。还有加了一个IDUID对吧,其他的这个是默认的,配默认帮我们加上了这个叫索引力度8192,因为它是一个什么呢,跳数索引就稀疏索引呢。
07:00
它有一个参数啊,那其他的就是咱们写的呗,这一块是咱们写的呗,对吧,那touch是装载的意思,说白了就是生效嘛,有用呗,那相反呢,叫detach就卸载对吧。Detached。啊,大概是这么拼的啊,卸载就是你查不到这张表啊,但是数据它还会临时帮你存一下啊,这就是原数据啊,其实很简单嘛,直接把你整个语句存下来,好,咱们回到最开始的路径,下面我们看一下贝塔CD推塔,好进来你看这俩是啥。刚才见过了呗,库名呗,这是库名,所以大家能看到库名,它怎么存呢?一个目录的名字,这是一个目录,再我们看一下default再进来,你可以看到这两个名字是啥呀。表明,哎,对,没毛病,你看这就是以路径来存的啊,目录名那后面是它指向的真正存储的嘛,但是后面这种不方便阅读对吧,它是存在store文件夹下面还有一堆编号啊,那咱们通常就看这个就行了啊呃,比如说看一下t order这张表。
08:15
MT,对吧,进来。这几个东西那是什么,什么叫tach,我刚才讲了是不是卸载的意思啊,你看一下默认这里应该是什么空的,对吧,咱们没有做什么操作好,另外这个就是格式版本的啊,你想看的话就看一眼。现在也是空的呗,因为啥也没做,那这边这个是啥分区目录。对吧,OK吧,没毛病吧,是不是跟have有点像啊,但它是在本地磁盘啊,那你看看,但是前面这个值是什么,是不是日期,也就咱们的分区字段了,是不是2020年6月1号,你再看看咱们数据。是不是就是这个值啊。
09:01
分区的值嘛,对吧,但是它后面是不是跟上了三个东西啊,拼接上了三个数字啊,这是啥意思呢?这个是它内部的存储结构,第一个数字一表示它的最小分区块的编号。最小编号。最小编号,那第二一个呢,是它的最大编号。最大变化,那最后一个值呢,是合并的等级,你想想我的是不是涉及到合并,咱们之前也讲了呗。涉及到合并对吧,哎,反正一会咱们要聊那个分区合并,咱们来看看这一个的变化对吧,那我先把提前把它截个图可以吧。把这两个东西截个图啊,我先丢在这里啊,一会再来看啊,那我们随便进入到比如说一一号的分区对吧,CD20200601对吧,这个分区你看。这么多个文件呢,这么多个文件,那分别是什么意思啊?
10:04
那首先咱们关注几个重要的啊,首先是他。它叫什么数据文件。也就是说咱们表里面的数据就在这里面,那么大家注意这边有一个版本的差异,咱们当前是什么版本,21.7,还有新的版本对吧?那如果是老的版本,它并不是这么存的,老版本它是什么呢?它是这样,咱们有几个字段我看看啊。四个字段对吧,啊,我我我我也截个图呗。啊,随便截一个吧,好,丢在这里。那如果是老版本,这个是点并结尾的跟点R结尾的,并不是只有这两个,它它老版本是按例名取的,它是这样,它有一个文件会叫id.B还会有个文件id.MRKR。
11:01
要代表ID这一列,那么所谓的病呢,就是存储它的真正数据MMRK呢,存储的是一个偏移量,也就是说到第几行了啊,它是呃,起到一个加速的作用,这个MRK啊,它是叫标记文件啊,标记文件就是说什么呢?我索引跟数据之间我加一个标记文件,就方便我去查找,就这个意思,大家知道就行啊,那那我们四个字段,它注意的就是这样啊,点B,然后SKU id.MRK,呃,MRK2,然后呢,再来一个就是total amount.b呃,Total amount.mrk2,然后再有一个create肽点并create肽点MRK2,大家能看到它的特点的呗。这是不是一个力?这是不是也是一个列,这是不是也是一个列,这也是一个列,对吧,它老版本里面,咱们看到线下跟这个版本不一样,它是只有一个列啊不每一个列都会单独存一个什么bin文件。
12:07
每一个列都会单独一个。那么咱们的这个RK呢。一个字段也有一个,但目前新版的里面合并数这个引擎,它是一共只有什么。一个。点并,当然仅仅针对合并数这个引擎啊,就tree没有前缀的这个引擎啊,其他引擎不一样,现象不一样啊。所以它只剩这一对了啊,那其他的是什么呢?呃,这个应该看得明白吧,默认压缩格式嘛,他把我们做了压缩,那还有其他的我们要认识啊,这个是什么?count.tst,我们看一眼啊。现在是一是返回了,返回多少啊?五说明什么?有五条数据,所以大家想想,假设我一张表有10亿条数据,我现在做一个select count新from这张表,它能在几毫秒之内立马就返回给我们,结果为什么呢?因为它有存了这么一个文件,记录了这张表的行数,那它怎么实现了?你每一次的插入它都会记下来,更新掉这个值,另外呢,他不是要合并吗?
13:22
呃,如果是其他引擎做合并的话,它也会把合并后的条数也记录下来啊,相当于说hi的一个什么原数据库啊,里面是不是也存储了行的信息,但那个不准对吧。这个是比较准确的。这就是他快就这就是体体现出了什么战斗民族的一个什么简单粗暴,你不是要查吗?好啊,我记好了,我给你就是了呗,对吧,很简单啊,那这个columns是什么意思呢?列的信息我们来看一眼。就是把你的列名跟类型记录下来,因为你想想你是不是回头得。
14:05
想要查找这张表的结构信息啊,也就是他的列名跟对应的列的类型啊,那他这里也记录好了对吧,也你看就是这么简单粗暴直接对吧,你要啥我给你记下来,那这个是一个校验信息,你可能看不懂啊。对吧,你看这玩意儿你看得懂吗?有一些信息是乱码的看起来,但是呃,这边是一个校验信息啊,校验信息这个不是给咱们看的,对吧?呃,那还有几个东西,可能大家看不太懂,那就首先是这个。这个是什么索引文件组件的索引文件。组件索引,咱们不是指定一个primary key吗?对吧,那它索引就是这个。那它的索引是什么?呃,大家可以简单了解,可能有的同学不太理解,咱们也不展开,它是一个稀疏索引,稀疏的索引,什么叫稀疏索引呢?比如说我有数据,一二三四五六七八九十。
15:08
难道我要把每一条数据,比如说这个是ID字段对吧?我对ID做了一个索引,难道我要把每一个ID都记录下来吗?索引文件里面不,它是这样,我一记一个,比如说他的索引文件是123对吧?这是他自己的编号,然后呢,他把第一条数据记录下来,是一,那中间在跳嘛。稀疏嘛,就不密集嘛,你看接下来我记录三,我把三记录下来,在接下来我记录一个八,把八记录下来。你看从这里来看,这个是被跳过了,这个是被跳过啊,这就跳数索引嘛,系数索引,当然咱们只是简单的一个抽象啊,这个就是一个primary key呃的索引文件,我们看一下,呃,当前呢,你一个E对吧,你也不知道他啥意思。
16:00
主要是什么,因为它还有这些东西你看不懂啊,啊看不懂啊,那还有一个什么呢?哎,重新展示啊,这个是什么分区呗。分区信息呀。对吧,你也看不懂啊,你知道它是用来表示分区的就行啊,分区的一个索引文件,那这个呢。这个才是真正分区内部的索引文件。这表示什么呢?最小。的值跟最大的值,你看ids结尾了,你记住就行了,是索引,但这个给谁用呢?给分区用啊,给分区用你也看不懂啊,对吧,这两个索引文件啊呃,行,这是咱们的一个目录介绍啊,目录介绍那如果你不好记,我这边已经给你整理好了啊,整理好了。哎,Primary key primary.ids咱们刚才看的是一个索引文件对吧?M max分区线的最大最小值对吧,为什么?记住这个它自然有用呗。
17:10
对吧,他的查询的时候肯定会用一些,呃,快速的算法需要用到这个值啊。还有这个什么我们看不懂的校验文件,校验它的正确性啊,大小值,哈希值啊,说白了就是有没有被篡改啊什么之类的啊,呃,Bin文件呢,就数据文件,MRK呢,就标记文件,它是在索引文件跟bin数据文件之间起到一个桥梁作用,说白了也是用来做什么加速啊。那老版本是MRK2,咱们是RK3的对吧,这个无所谓,反正咱们也不会去改这个东西,它一般会记录什么呢?一个列的一个offset,就偏移量,一般是记记录了这个东西,呃,那我们既然如此,我们再聊一聊这个东西。我们当时说了第一个。
18:02
下划线前面呢,我们看得懂,分区的值,后面三个数字什么意思呢?这边我特意单独给大家摘出来了,它是这么一个规则,第一个是分区ID,也就分区的值,第二一个是最小块的编号,最大块的编号,还有一个合并的层级,我翻译成中文单独写了一个啊,那每一个都有解释啊,那首先分区的ID其实没有那么简单啊,它是有一个规则的。首先它由分区键决定的,而且分区键的字段是很有讲究的,同学们,这点你要注意了啊,分区的字段类型如果你没定义,我们说了会生成一个目录名为or的数据分区,对吧?这个不用讲啊,一般生产不会这么用。还有一种是什么整形跟日期类型的,这个我们可以看成同一类啊,如果为整形就INT8INT,呃32T64那些嘛。
19:01
直接用该整形的字符串形式作为IDE,说白了你长什么样?你的分区值是123,那它的目录这里显示的就是123,还有一种日期类型,这点要注意啊,这一点要注意,如果分区键为日期类型。要么你要必须可以转化成日期类型,什么叫可以转化成日期类型,这点大家注意啊,比如说我是一个这个字符串,我本身存的就是字符串。我分区键是个字符串,不是数日期类型,但是它也可以用,为啥?因为它会帮你转成日期类型。对吧,你手动转也可以啊,手动转也可以,你可以用to date嘛。To date是不是呃转成date类型啊,Date是不是年月日啊,对吧,To date函数,然后把它传进来。那么大家想一想,我直接存了一个日期类型,跟我存了一个字符串再去转换,哪个效率高?
20:05
你是不是直接存了一个日期类型更好?这边这一点为什么要强调?区别于have have,咱们一般为了方便统一日期,都存成了string,对吧?但click house不是这样,如果从性能角度讲,你最好直接存储的类型就是一个日期类型会比较好一点。也比较好一点啊,行,这不多说,如果是其他的注意了,如果无法转成日期类型也好,其他的string还有浮点型。他会怎么样,先取一个哈希算法。把哈希值作为分区ID,也就是说未来你的分区键不是上面这两种,呃,然后呢,你看到这个目录里面第一串第一部分的值,它是一个你看不懂的,什么0A3CB什么什么一堆值啊,或者就是哈希值,这个你要看得懂啊,那最小分区块的编号它是自增的,它从一开始增嘛。
21:04
每产生一个新的目录,分区就向上递增一个数字,对吧,那最大的分区块编号呢?如当然了,你会看到我们这边数字都一样,对吧,1122,一个最小一个最大,怎么一样呢?因为咱们还没有。产生所谓的合并,那包括第三个跟合并相关,表示合并的次数,对吧,进行过几次合并,这个就我们要往下来看了,往下看你就能看到这三个值的一个变化。变化好吧,行,这个是咱们关于目录文件,呃,还有一些命名规范的介绍,当然讲的可能过分详细,对吧,你你也不用着急,记住就是什么呢,这个文件我回头也保。保存下来让大家忘了,之后呢,你就翻开看一看就行了啊。
22:00
行,那咱们接下来做一个什么事呢?我再次插入啊,咱们要来玩这个了。为什么前面一直讲到合并合并合并啊,对吧,还有什么分区块啊,其实是这样的,它每一个批次的数据写入都会产生一个什么临时分区。它并不是直接插进去的,同学们并不是根据分区插进去的,它之后呢,它才会执行一个什么叫做合并操作,这个咱们前面谈到了特点里面h base,呃,咱们是不是也有一个叫大合并小合并呢?只有大合并的时候,它才会清除过期的数据,对吧?啊一样的,因为而且base也是一个op数据库。查询,呃,查询分析型的数据库跟click house一样,他们都是这种原理对吧,那你想想我每次插入都是一个临时分区,但是他们迟早是不是得进入到真正的分区啊,这个时候就会就是需要等一个合并操作,那这个合并操作跟H被子一样,它也是定期执行的啊,定期执行的并不是说立马触发的,因为它合并的过程你肯定没法对外提供服务了呗。
23:19
对吧,所以要谨慎啊,这个东西,那我们可以通过手动执行的方式。也可以手动触发了,当然了h base也可以呗,对吧,用这个语法就可以手动触发,那其实这个语法还可以加一个什么分区,我只触发某一个分区的合并,加一个关键字partition就行啊行,我们先演示呗,呃,我们这样,我先查一下这张表,呃,现在是不是两个分区啊,能看到对吧?好,那接下来我再执行一次插入,大家注意这个跟数据跟刚才一样,对吧,也有6月1号的跟6月2号的,跟咱们前面插入的是一样的,好,我直接粘过来。
24:02
穿过来之后,来我查你看有什么现象。有啥现象?你看啊,6月2号,6月2号这两个不应该是同一个分区吗?但是你看他们在一起吗?他们没在一起。这就跟那个牛郎牛郎织女一样,他俩是不是相爱的,讲道理他俩应该在一起对吧,但是由于某些原因是被分开了,他们是不是只有一年定期一年一次才能相会啊,才能水乳交融,合为一体啊,啊,不是啊,才能那个呃。解相思之苦对吧,才能在一起,一样的道理,虽然你俩是一个分,讲道理属于同一个分区,但是并不是立马在一起,他需要等什么合并对吧,就跟牛郎织女等七夕一样,鹊桥搭建的时候才能相会啊,那我们这个时候呢,其实其他的也一样,你看一号的,一个是新插入一个刚插入的,你看分开的吧,那我们看一下这个路径啊。
25:15
是不是多了两个,但讲道理,你看6月1号的分区有两个呗,最小块三,最大块也是三。什么叫快呢?呃,原先是不是有这两个?那后来要生成一个新的,它的编号是不是从三开始,对吧,所以它是三,然后6月2号新的临时目录是不是从四开始,但是这样我们说不合理对吧,所以我们执行合并的话,它俩会合成一个。他俩会合成一个。这个时候。这个值跟这个值就不一样了啊,这两个值就会变成不一样了,第三个值也会变啊,我们来试试,来手动。来执行这个命令,我拷贝前面的就好,呃,然后表明是t order用T对吧,加一个final。
26:09
回车OK了,同学们注意看啊。我把这个再截个图。我现在还没重新查对吧,好这个时候再看一下。有了一个什么。再多了一个什么,我们看一个分区就好了,看一号分区。是不是多了一个131。对吧。可以理解吗?最小说白了就是这个意思嘛,呃,我这个跟这个要合并,那它们两个之间最小的编号是谁?是不是一呀,所以这个值就确定了,是一呗。那它俩之间在下划线在拼接上一个最大编号,它俩合并的话,最大编号是谁啊三呗。对吧,好,最后一个数字是什么?合并了几次对吧,经历了几次,合并是不是一次。
27:04
OK,不?那有的同学会想,那原来这两个路径呢?数据还在不在,我们瞅一眼啊啊110最原始的这个数据是不是还在那三的那个就不用看了,我们再看一下合并后的啊,20201,然后131好进来。是不是也有啊,对吧,但是他最后会清理的啊,最后这两个会被清理掉的,当然他需要等那个真正合并的时候,真正合并的时候。这两个东西会被清掉,这两个就相当于过期数据了啊,过期数据了。现在大家能理解这个过程吗?它并不是。他这个合并的概念是很重要的啊,合并。盖下去被子有点相似啊,有点相似。
28:00
嗯,那我刚才还提到说这个语法手动执行是不是可以指定某个分区啊。对吧,因为你大家可以看到这里的话,呃,这个二号分区是不是同时也执行了一次合并啊。对吧,那如果我只想到某一个分区合并呢,也可以,我现在这样,我插数据的话只差一条同学们。只差一个分区吧,也别说只差一条了,那就这我只差6月1号的啊,只差6月1号啊,或者我都插呗,都差啊,我再插一遍。好了,这个时候咱们,诶。啊,你看。嗯,我看看啊,这个是之前合并过的,这个也是之前合并过的,对吧,这两个是老的,那这个是不是新插入的,这个后面也是新插入的,但是还没触发合并对吧?当然讲的越多可能有点绕了,大家不会乱吧,你看对于。
29:15
一来讲。一号的分区是不是多了一个临时目录啊?550对吧,对于二来讲,是不是多了一个目录660啊,我同样截个图啊。来放这儿,然后呢,刚才那个语法。好,这里我加一个partition。呃,叫什么呢?我想想啊一下啊,好像是这样,呃,这样一个part,然后part的值对吧,我们是20200601啊,这是ID啊,我看一下。啊,那这个语法还不是这么用的啊。
30:03
那个我们看一下官网呗。呃,在哪里呢?在这儿啊。Circle reference,然后呢,你点这个statements语法,然后往下拉有一个这个优化语法啊,你看它是可以写一个partition。加一个final。呃,但是他的事例里边倒没有啊,那可能是我记错了。行,先玩到这儿呗,你看下面的例子,也没有什么partition是吧,回头再看看啊。或者说应该是不加final也不行啊。行了,先不管他了吧。那咱们通常就是这么来用的啊,通常就是这么来用的。Final,那么这个final我可以简单再提一句啊,其实咱们早期。
31:03
呃,这个final它是单线程的。大家注意老的版本final是单线程的,但是当然是查询,跟这个没关啊,不是优化语法,比如说你select什么final那个那个这个咱们在高级里面会介绍啊,那现现行,现在先不提这个事儿啊,现在先不提这个事。那我们。最后再做一个什么,我们再优化一次呗,啊再优化一次。Final好了,再看看它的一个目录变化,你看。呃,看一号分区的啊。多了一个什么。是不是多了一个这个。现在这三个数字大家能理解了吧?呃,首先是一个分区号,6月1号,OK,第一个数字一是什么意思?最小的编号是谁啊?一好,下划线在拼接上,下一个数字最大是谁呀?它是不是有一有三有五啊?那最大是不是五啊?
32:14
好,执行了几次合并啊。是不是第二次合并啊,所以152看得懂了吧啊。就是这么一个过程啊。那关于刚才那个问题就是什么呢?我刚才不是想演示一个partition吗?是针对某一个分区进行一个什么一个合并操作,其实我少打了一个字母T,对吧,漏打了,那我们可以再执行一遍,你看。合并表对吧,然后partition只针对。这个数据进行一个合并啊,这是可以的啊,只合并某一个分区,那么大家自己再去玩一玩啊,你可以插入几条数据,然后呢,执行这个语句,你可以看到这个分区它目录数据目录里面变化了,对吧?啊,那几个编号变了啊,多了几个临时多了临时目录,那么其他另外一个分区它是不会的啊。
33:10
我这只是随便敲一个啊,那哦,我们那个是0601对吧?啊,大家可以再去玩一玩啊,你看事情是没毛病的啊,这个给大家算补充说明一下啊。
我来说两句