在一次对比oracle和greenplum查询性能过程当中,因为greenplum查询性能不理想,所以进行定位分析,提高greenplum的查询性能html
初始状况下,搭建一个小的集群,进行性能测试node
磁盘 | SAS |
交换机 | 千兆 |
集群大小 | 4segment |
数据量 | 3亿 |
数据文件大小 | 68G |
表类型 | Heap 行表 |
字段类型 | 全部列为varchar |
列宽 | 41列 |
索引 | 无 |
查询语句 | select count(*) from xxx where gjdqdm = 'CHN' and crrqsj >= '20100101000000' and crrqsj <= '20180101000000' and crkadm = '055' |
PS:因为要求greenplum中的表数据类型和源表类型一直,且索引一致。因此全部字段都为varchar类型且无索引,所以这方面没有优化空间。sql
SQL | ORACLE耗时 | greenplum耗时 |
select count(*) from xxx where gjdqdm = 'CHN' and crrqsj >= '20100101000000' and crrqsj <= '20180101000000' and crkadm = '055' | 24S | 14.1S |
14.1S是不能接受的速度,所以须要查找缘由,以期找出性能瓶颈,提供优化方案oracle
从①处能够看出,全部的耗时都在③的操做,seq scan上。post
这里①处的意思是(摘自官网):性能
The numbers that are quoted by EXPLAIN are (left to right):
Estimated start-up cost (time expended before the output scan can start, e.g., time to do the sorting in a sort node)
Estimated total cost (if all rows are retrieved, though they might not be; e.g., a query with a LIMIT clause will stop short of paying the total cost of the Limit plan node's input node)
Estimated number of rows output by this plan node (again, only if executed to completion)
Estimated average width (in bytes) of rows output by this plan node
③处的意思是:顺序扫描磁盘测试
从②处能够看出,全部的segment都参与了查询优化
从④处能够看出,全部的列设置为varchar都进行了类型转换,转成了text,且没有走索引(也无索引能用)this
从⑤出能够看出,实际使用的内存远小于分配的内容,因此这里能够判断出问题不在内存spa
这里能够看到数据分布是很是均匀的,因此不存在其中一台计算节点耗时特别长的状况
既然内存没有问题,那就能够尝试看CPU和磁盘的使用状况了
在其中计算节点使用top命令查看:
这里是其中一台计算节点的截图,这里说明仅仅对于这一条SQL而言,已经消耗了CPU100%的资源,可是整机还有至关富余的CPU资源可用
使用sar命令查看计算节点状况
PS:这里仅展现一套机器(实际状况中每一台计算节点都是相同的状况)
这里发现iowait一列是基本都为0,可是idle也为0,此处验证了磁盘io没有问题,问题出在CPU上
前面说到这个greenplum集群创建的时候只在每台结算节点分配了一个segment,因此每台机器上只有一个CPU是忙碌状态的,而其余的CPU处于空闲状态
充分的利用CPU资源,就能够显著提升查询的性能。
所以,对这套集群的segment进行扩容,将原来的4个segment扩容为54个,而且从新建表后将全部varchar类型换成text,将参与查询的日期列设置为分区键,分布键不变,仍为id列
oracle | 原集群 | 扩容后的集群 |
24S | 14.1S | 1.5S |
https://www.postgresql.org/docs/9.2/static/using-explain.html