大多数用户在体验数据库时,接触到的最早的sql语句就是count(),因此用户判断数据库性能时通常也会通过count()进行比较。但在执行时通常会出现一个问题:对某个表做count(*)时需对全表数据进行扫描,当表中包含数据量较大的字段时,IO将会成为数据扫描的瓶颈。
数据扫描瓶颈有哪些优化方式?
针对上述问题,为解决全表扫描带来的IO开销的方案大致可分为三类:第一类是减少扫描数据;第二类是通过并行方式扫描数据;第三类是通过预估值计算方式获取结果。根据上述三种方案,我们给出以下四种优化方式:
1、减少扫描数据
(1)使用列存
顾名思义,列存是按列存储的。当使用count()查询时,只需要扫描一列数据做count统计,而并非全表,这样,IO开销几乎是行存的1/列数,即效率是行存的列数倍。在实际使用中,因为每列字段长度的原因,使用列存时count()效率往往要比这个值还要高得多。
(2)使用Index only scan
使用主键的Index only scan,count(*)仅需扫描主键的索引链表即可,不必扫描所有的数据块,以此可大大减少IO开销。
2、并行扫描数据
(1)MPP架构
使用MPP架构的好处是让数据分布到各个计算节点上。这样,在使用count(*)查询时,每个计算节点都会去统计该节点的数据量,最终汇聚返回总的数据量,这种方式可以更好地利用CPU和磁盘达到并行扫描的效果,节省扫描时间。