select 字段 from 表 [limit 3];
Hive中
select *
与select 全字段
的性能比较,select *
查询速度更慢?Hive中
使用limit关键字
比不使用limit关键字
更慢?
1.测试数据
student
表结构
hive> desc student;
OK
stuid int
name string
sex string
age int
dept string
Time taken: 0.054 seconds, Fetched: 5 row(s)
数据主体如下
(22条数据)
hive> select * from student limit 3;
OK
student.stuid student.name student.sex student.age student.dept
95001 李勇 男 20 CS
95002 刘晨 女 19 IS
95003 王敏 女 22 MA
Time taken: 0.16 seconds, Fetched: 3 row(s)
2.查询
1)测试 *
查询所有字段
select * from student;
直接查看SQL执行计划
hive> explain select * from student;
OK
Explain
STAGE DEPENDENCIES:
Stage-0 is a root stage
STAGE PLANS:
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
TableScan
alias: student
Statistics: Num rows: 1 Data size: 547 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: stuid (type: int), name (type: string), sex (type: string), age (type: int), dept (type: string)
outputColumnNames: _col0, _col1, _col2, _col3, _col4
Statistics: Num rows: 1 Data size: 547 Basic stats: COMPLETE Column stats: NONE
ListSink
Time taken: 0.224 seconds, Fetched: 17 row(s)
① state 依赖:
对于 select * 只需要一个stage即可完成,不需要依赖其他stage, state-0 即唯一的阶段
② stage-0阶段:
主要有如下Operator:
Fetch TableScan Select
Fetch:主要去hdfs目录找到对应表文件
TableScan:控制扫描数据行数
Select: 选择输出列
类似这样的查询,相当于直接通过Hive 自带的Serde去按照分隔符解析文件。对于*的话会直接扫描整个表把整个表文件的数据拿过来( limit -1 ),整个过程中只有hdfs操作,没有mapreduce作业的执行。
2)多字段查询与limit关键字
我们来看看按照选定的字段。
hive> explain select stuid,name from student;
OK
Explain
STAGE DEPENDENCIES:
Stage-0 is a root stage
STAGE PLANS:
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
TableScan
alias: student
Statistics: Num rows: 5 Data size: 547 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: stuid (type: int), name (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 5 Data size: 547 Basic stats: COMPLETE Column stats: NONE
ListSink
Time taken: 0.108 seconds, Fetched: 17 row(s)
同样是:一个阶段(stage),limit -1
扫描所有行,然后扫描对应列就行了。
然后是limit
:
hive> explain select stuid,name from student limit 3;
OK
Explain
STAGE DEPENDENCIES:
Stage-0 is a root stage
STAGE PLANS:
Stage: Stage-0
Fetch Operator
limit: 3
Processor Tree:
TableScan
alias: student
Statistics: Num rows: 5 Data size: 547 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: stuid (type: int), name (type: string)
outputColumnNames: _col0, _col1
Statistics: Num rows: 5 Data size: 547 Basic stats: COMPLETE Column stats: NONE
Limit
Number of rows: 3
Statistics: Num rows: 3 Data size: 327 Basic stats: COMPLETE Column stats: NONE
ListSink
Time taken: 0.101 seconds, Fetched: 20 row(s)
Fetch:从hdfs找文件,但是解析文件的时候只读了3
行,为什么这么说呢?你可以直接对比select * from student
和select * from student limit 3
执行的毫秒数.差距是很明显的,数据量大的时候更加明显。
Select:主要是选出对应列即可
结论:
① 类似select 字段列表 from 表名 limit 条数;
这种简单的标准查询,全字段查询
和*
是没有区别的,不存在说谁快谁慢,都是全列扫描hdfs文件。这与传统的关系型数据库明显不同,更不比说查询某些字段速度更快啥的。当然如果创建索引的话就另说了。但是即便添加索引的话,也要考虑到索引也会消耗额外的资源去创建索引和空间存储索引
。
② 类似select 字段列表 from 表名 limit 条数;
同样的,对于limit
关键字,在传统关系型数据库中,limit是全表扫描后取对应的行数,因此常常听大佬说不要使用limit
关键字。但是对于Hive而言,可不是这样的,你limit
几行就查询几行,其他的也不会被扫描到,所以使用limit反而比不使用limit查询速度更快
。