数据仓库(十三)--java--presto---SpringMVC使用presto查询hive

我们对8400万条hive数据使用presto进行查询,数据量大约11G,不是很大。

尽量不适用or语句

前端web界面上只有一个输入框,通过这个输入框同时查询三个字段是否有相等的数据

使用查询语句主要涉及三个字段为:

select chromosome,position,rs from chip where 1=1 and (chromosome='156531656' or position='156531656' or rs='156531656' ) limit 20;

发现查询时间花费较长,花费在35s左右。

优化,对表进行分区处理,生成新表

create table chip_pt(id BIGINT,position  string,rs  string,linenum  string,filename  string,createdate  string) partitioned by (chromosome  string);



set hive.exec.dynamic.partition=true;

set hive.exec.dynamic.partition.mode=nonstrict;

set hive.exec.max.dynamic.partitions.pernode=100000;

set hive.exec.max.dynamic.partitions.pernode.Maximum=100000;

set hive.exec.max.dynamic.partitions=100000;

set hive.exec.max.created.files=100000;

set mapred.max.split.size=1024000000;

set mapred.min.split.size.per.node=1024000000;

set mapred.min.split.size.per.rack=1024000000;

set mapred.reduce.tasks=100; 

set hive.map.aggr=true;

set hive.groupby.skewindata=true;

set hive.enforce.bucketing = true;



insert overwrite table chip_pt

partition(chromosome)

select  row_number() over (order by position) as id,position,rs,linenum,filename,createdate,chromosome   from chip;

尝试查询发现当 所选参数是 分区字段时,查询速度很快,能达到300ms级别。
但是,如果使用的非 分区字段内容时,查询的时间还是在 30s左右。

我们把三个字段分开来进行查询尝试。
发现只要带有准确的分区字段chromosome内容的查询 条件 耗时都为 ms级别。

select position from chip_pt where chromosome='8' and  position='156531656'

单个非分区字段position或者rs的查询 耗时为15s左右。

select position from chip_pt where  position='156531656'

使用explain分析查询sql如下:

explain select position from chip_pt where  position='156531656'

发现单一的条件扫描了全表。

使用or语句时,会一次扫描多次遍历全表。

所以我们需要在交互逻辑上优化sql语句,把查询输入框由一个拆分成三个,然后根据输入框是否为空,使用and来拼接查询语句。尽量少用or语句。

增加索引

因为非分区字段的查询时间达不到1s内的查询要求,所以我们想进一步优化,除了分区之外还有一个思路就是加索引。

使用语句

增加索引

create index chip_index_position on table chip_pt(position)

as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'

with deferred rebuild;



create index chip_index_rs on table chip_pt(rs)

as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'

with deferred rebuild;



alter index chip_index_position on chip_pt rebuild;

alter index chip_index_rs  on chip_pt  rebuild;

增加索引后在presto中原语句查询发现并没有显著增加查询效率,时间还是在15s左右。

select position from chip_pt where  position='156531656'

以为索引 没生效。但是使用explain查看以及在索引表中查询 都能查询到索引。
使用语句查询索引表

select position from chip_index_position where position='156531656';
desc chip_index_position;

使用explain分析查询索引表语句。

explain select position from chip_index_position where position='156531656';

发现在查询索引表时也需要全表扫描索引表,花费的时间本来就有13s左右。

所以也就是说 针对少数据量,索引并不能把presto查询hive的效率提高到1s内,最极限就是达到 查询索引所花费的时间。

总结

1、hive的sql语句在使用时尽量少用or语句。
2、即时针对hive我们有presto这样的实时交互引擎,但是它优化的程度还是有限的,瓶颈就在索引扫描花费的时间上,所以如果是针对小数据量,要求1s内返回的查询场景,尽量不要存在hive,存在mongodb,mysql,hbase等场景比较合适。

你可能感兴趣的:(数据仓库)