天天看點

Apache Hive 執行流程之select标準查詢

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查詢速度更快

繼續閱讀