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)測試 *
查詢所有字段
*
直接檢視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:主要去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查詢速度更快
。