大數據-Hive

Hive

Hive是一種用於執行離線計算的數據倉庫工具,基於Hadoop的HDFS與MR實現。html

Hive偏重於數據的分析和處理,使用映射關係將結構化的數據映射爲表的結構。java

例如:基於數據(1,zhangsan,123456,男)對應生成(id+uname+pwd+sex)的映射mysql

Hive不會直接影響原始數據的結構,而hbase須要將數據存到hbase數據庫才能查找數據。linux

Hive可以實現非Java用戶對HDFS數據的MR操做。web

官網:http://hive.apache.org算法

數據倉庫

  • 分爲OLAP聯機分析處理,OLTP聯機事務處理sql

  • 經過對以往數據的分析,對現有和將來業務提供數據支持數據庫

  • 對數據處理分爲:apache

    OLAP聯機事務處理,負責數據事務處理,關係型數據庫的主要應用json

    OLAP聯機分析處理,負責數據分析處理,數倉的主要應用

  • 數倉中的數據模型包括:

    星型模式(單一中心節點)

    雪花模型(一箇中心節點多個分支節點)

    星系模型(多中心節點)

  • 數倉基本用於執行對數據的查找和統計,通常不會刪除數據或修改數據

  • 詳細參考:https://zhuanlan.zhihu.com/p/67446501

Hive架構

  • client

    客戶端包括三種方式

    命令行模式——直接經過HQL(Hive Sql)執行操做

    JDBC/ODBC模式——經過java代碼操做,需藉助ThriftServer將代碼轉爲HQL

    WebUI——經過web端輸入HQL,遠程執行任務

  • MetaStore

    • 元數據存儲器,用於存儲Hive建表語句,也就是描述Hive與數據的映射關係的數據

    • 元數據包括:表,表的列、分區、屬性、表的屬性,表的數據所在目錄

    • 元數據會存放在關係型數據庫中(mysql)

  • Driver

    • 解析器——將hql解析爲語法樹

    • 編譯器——將語法樹轉換爲邏輯執行計劃

    • 優化器——重寫邏輯執行計劃實現優化

    • 執行器——將邏輯執行計劃轉換爲物理執行計劃(MR-JOB)

  • 基於Hadoop-Yarn+Mapredce+Hdfs執行物理執行計劃

Hive搭建

  • 前提:mysql與Hadoop安裝完成

  • 在mysql中添加一個庫用於存放Hive的映射

    create database hive_single;

  • 將安裝包解壓到指定位置

    tar -zxvf apache-hive-1.2.1-bin.tar.gz

    cp -r apache-hive-1.2.1-bin /opt/sxt/

    mv apache-hive-1.2.1-bin hive-1.2.1

  • 修改配置文件

    cp hive-default.xml.template hive-site.xml

    刪除原始內容中configuration標籤下的內容(3891行)填入以下內容

    <!--hive數據在hdfs中的路徑-->
    <property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/hive_single</value>
    </property>
    <!--是否本地單機模式-->
    <property>
    <name>hive.metastore.local</name>
    <value>true</value>
    </property>
    <!--mysql鏈接,須要指定數據庫名,例如hive_single-->
    <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost:3306/hive_single?createDatabaseIfNotExist=true</value>
    </property>
    <!--mysql驅動、用戶名、密碼,注意這個是liunx中安裝的mysql-->
    <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
    </property>
    <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
    </property>
    <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>123456</value>
    </property>
  • 拷貝mysql的jar包到lib目錄(mysql-connector-java-5.1.32-bin.jar)

  • 解決Hadoop與Hive的jar版本差別(將jline文件替換)

    cd /opt/sxt/hadoop-2.6.5/share/hadoop/yarn/lib/

    rm -rf jline-0.9.94.jar

    cp /opt/sxt/hive-1.2.1/lib/jline-2.12.jar ./

  • 配置PATH

    vim /etc/profile

    export HIVE_HOME=/opt/sxt/hive-1.2.1 export PATH=$HIVE_HOME/bin:$PATH(注意加上其餘軟件的路徑)

    source /etc/profile

  • Hive啓動命令:hive

    查看庫命令show databases;

    建立庫create database myhive;

    使用庫use myhive;

    建立表create table user;

  • 保存快照

Hive-SQL

數據類型

基本類型

  • 整型

    int(4byte) tinyint(1bety) smallint(2byte)bigint(8byte)

  • 浮點型

    double(8byte) float(4byte)

  • 字符型

    string char(定長) varchar(不定長)

  • boolean型

    true/false (1位)

  • 時間型

    timestamp時間戳 date日期

類型轉換

  • 自動

    整型隱式轉爲範圍大的整型

    全部整型,float,string能夠隱式轉爲double

    int,tinyint,smallint能轉爲double

    double不能轉型爲其餘數據類型

  • 強制

    例如:cast('1' as int)

  • 表設計時須設置合適的數據類型避免類型轉型

引用/複合類型

由基本類型構成,複合類型能夠相互嵌套

  • Array

    • 存放相同類型的數據

    • 以索引排序,索引從0開始

    • 獲取數據的格式爲:user[0]

  • Map

    • 存儲任意數量的鍵值對,適用屬性的數量和類型均不肯定的狀況

    • 經過key取值,map['key1']

    • key不能相同,相同的key會相互覆蓋

  • Struct

    • 結構體,內部的屬性與屬性的類型固定

    • 經過屬性獲取值:info.name(獲取info結構體中name的屬性)

DDL庫操做

  • 建立數據庫

    create database sxt;

    create database if not exists sxt;

    create database sxt location '/hive_single/sxt_path' 指定數據庫在hdfs的路徑(路徑名與數據庫名可不一樣,建立時不會將原路徑數據清除)

  • 刪除數據庫

    • drop database if exists sxt cascade;

      刪除庫,並將庫所在文件夾刪除

    • drop database sxt ;

      刪除空庫

  • 使用數據庫

    use sxt ;

  • 查看數據庫

    show databases;查看全部數據庫名

    show databases like 's*'; 匹配查找數據庫

    desc database sxt;查看庫內的表

  • 修改數據庫(瞭解)

    沒法修改數據庫名和數據庫所在路徑。只能修改其餘數據

    alter database sxt set dbproperties('createtime'='20170830');

DDL表建立

  • external 是不是外部表,不加該關鍵字則默認內部表

  • 定義每一列

    全部列在括號內,相互經過逗號分隔

    (col_name data_type [COMMENT col_comment], ...)

    • 普通列: name string

    • 數組: books array< string>

    • map: score map<string,int>

    • struct: info struct< name:String,age:int>

  • COMMENT col_comment 列註釋

  • COMMENT table_comment 表註釋

  • 分區

    [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]

  • 分桶

    [CLUSTERED BY (col_name, col_name, ...) ]

    [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]

  • 每一行的數據切分方式

    ROW FORMAT row_format

    • 字段分隔,array分隔,結構體與map的K-V分隔符,行分隔符

    • 注意順序不能改變

    • 默認行以\n分隔,能夠省略

    ROW FORMAT delimited 
    fields terminated by ','    
    collection items terminated by '_'
    map keys terminated by ':'
    lines terminated by '\n';
  • 數據存儲格式

    STORED AS file_format 用於數據壓縮等狀況

  • 數據文件的地址

    LOCATION hdfs_path

    內部表和外部表均能指定表HDFS路徑,LOCATION 是一個文件夾

    location '/hive_single/sxt';

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name 
(col_name data_type [COMMENT col_comment], ...)
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...) ]
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]

實例:

文本格式:
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing

json格式:
{
   "name": "songsong",
   "friends": ["bingbing" , "lili"] ,       //列表Array,
   "children": {                      //鍵值Map,
       "xiao song": 18 ,
       "xiaoxiao song": 19
  }
   "address": {                      //結構Struct,
       "street": "hui long guan" ,
       "city": "beijing"
  }
}
create table person(
  name string,
  friends array<String>,
  children map<String,int>,
  address struct<street:string,city:string>
)
row format delimited fields terminated by ','
collection items terminated by '_'
map keys terminated by ':'
lines terminated by '\n'

外部表與內部表

表默認爲內部表,使用external則爲外部表

表建立時都不會將已有文件夾中的數據清除。

內部表

  • 內部表處理獨享的數據,適用於單次處理的數據,不適合於其餘工具共享數據

  • 刪除表時表路徑中的原始數據也會刪除,若指定location的內部表會將location的一級目錄刪除

外部表

  • 定義表可定義location路徑,實現和其餘表共享數據文件

  • 刪除外部表時只刪除元數據信息,location目錄下的數據將被保留

    create external table person(name string) 
    location '/myhive/sxt';

內外表切換

  • alter table sxt set tblproperties('EXTERNAL'='TRUE'); 內轉外

  • alter table sxt set tblproperties('EXTERNAL'='FALSE'); 外轉內

表刪除與清空

  • 表刪除(外部表不清除原始數據)

    drop table [if exsits] t_user;

  • 清空表數據,直接截斷

    truncate table_name;

  • 查看錶結構

    desc table_name ;

表修改(瞭解)

  • 改表名

    alter table t_oldName rename to t_newName;

    內部表會將對應文件目錄名修改,若指定了location則將location原目錄移動到默認路徑下

    外部表不會影響location地址的數據,不指定location也不會對默認路徑進行修改

  • 更新列

    alter table table_name change [column] col_oldName col_newName column_type [column col_comment] [FIRST|AFTER column_name];

  • 增長替換列

    alter table table_name add|replace columns(col_name data_type [備註], ...);

數據載入

load載入

load data [local] inpath '/root/path' [overwrite] into table table_name

  • local,表示路徑爲linux路徑,不然默認爲HDFS路徑

  • overwrite,表示覆蓋載入,將表文件中原有的數據覆蓋,不然默認爲追加

  • load 加載不執行MR操做

  • local文件將被複制到HDFS的表目錄中,HDFS文件則剪切到表目錄。

insert載入

insert會啓動MR操做,通常用於將原表的查詢結果插入到新表中。

overwrite(覆蓋) 和 into(追加),能夠相互替換

單表插入

  • insert overwrite table t2 select xxx from t1;(將表1的xxx字段插入表2中)

多表插入

  • from t1

    insert overwrite table t2 select xxx1

    insert overwrite table t3 select xxx2; (將表1的xxx字段插入表2中)

單記錄插入(通常不這麼作)

  • insert into t1 values ('id','5'),('name','zhangwuji');

表數據導入導出

計算導出

經過insert將查詢結果保存爲數據文件,執行了MR操做且只保存數據文件

insert overwrite local directory '/root/data_out' 
row format delimited fields terminated by '-'
select * from mytable;

加入local表示導出到本地 linux的文件路徑中,不加location則表示導出到HDFS的文件路徑中

row format部分表示輸出數據的間隔方式,與表定義相似

直接導出

  • 導出,將表數據及表結構指定hdfs路徑下,在該路徑下保存元數據文件與數據文件夾。

    export table t_name to '/hdfs_path'

  • 導入,將文件夾導入到命名空間,直接在命名空間下生成導出的表及數據

    import from '/hdfs_path'

    恢復後的文件夾名與表名相同,表自生屬性也被保留(外部表屬性,內部字段等)

分區

爲了減小全表掃描查詢的問題,根據指定字段的值,對數據進行分區存儲(分多個文件夾存儲)

定義分區表

--定義分區表時,能夠指定多個分區屬性
create table t_name(id int,name string)
partitioned by (addr string , work string)
row format delimited fields terminated by ',';

分區層級分爲:單分區和多分區

  • 單分區:只有一種分區。按照單一屬性值分區

  • 多分區,包含存在父子關係的多種分區。先依據父級屬性分區,再依據子級屬性分區

分區操做

  • 添加分區 alter table t_name add partition(column='xxx');

  • 刪除分區 alter table t_name drop partition(column='xxx');

  • 查詢分區 show partitions t_name;

靜態分區

數據載入

load data [local] inpath '/path' 
into table 't_name' 
partition (column1='xxx',column2='yyy');

靜態載入的數據,會複製到對應的分組文件夾下,若無則自動建立文件夾。

數據只能載入到一個文件夾中,且查詢時hive直接從文件夾中取數據,再也不對分組字段處理。若文件中存在分組字段實際數據與分組數據不匹配,也將該字段值視爲指定的分組數據。

動態分區

  • 開啓動態分區指定以下

    set hive.exec.dynamic.partition=true;

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

  • 開啓動態分區後再建立主分區表

    create table table1(
    id int,
    name string
    )
    partitioned by (novel string,sect string)
    row format delimited fields terminated by ',' ;
    
  • 建立外部臨時表,臨時表的字段與主分區表字段相同,臨時表的location指向數據源

    create external table table2 (
    id int,
    name string,
    novel string,
    sect string
    ) 
    row format delimited fields terminated by ',' 
    location '/path' ;
    
  • 使用insert語句經過臨時表將數據載入主表,期間執行的MR操做

    insert overwriter table table1 
    partition(novel,sect) 
    select id,name,novel,sect from table2;
    

分桶

根據指定的列,對列值hash計算,根據結果將數據存入對應桶,可以將數據有效散列到桶中。分桶須要執行MR,桶的數量與reduce相同,計算結果輸出到對應的桶文件中。

效果:使得桶中的數據較爲均勻,便於統計計算。相同的key必然在一個桶中,下降表鏈接的數量。

數據插入:依賴於insert方式的數據插入

  • 指定列須要知足:常常被查詢,自身散列較好

  • 分桶能夠在分區的基礎上執行

  • 分桶的數據須要具有較多的公約數,便於查詢(12的公約數:1,2,3,4,6)

分桶建表語句

create table table01(
id int ,name string,age int) 
clustered by (name) sorted by (age) into 6 buckets 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
--說明
按照name屬性分桶,桶內經過age實現排序

分桶表的取樣SQL

tablesample(bucket x out of y on 分桶列 )

  • 第二個參數表示將桶分爲多少組,其爲分桶數的公約數

  • 第一個參數表示每一個組中取幾個桶進行計算

  • 參數1不大於參數2

select * from table01 tablesample(bucket 1 out of 3 on name );

複雜映射建表

經過正則將列與複雜數據進行映射,可以匹配複雜文本

--基本格式
create table table_name(column type,...) row fromat serde 'org.apache.hadoop.hive.serde2.RegexSerDe' with serdeproperties("input.regex" ="正則") 

正則中每一個括號內的部分對應前面定義的列

例子以下:

原始文件格式:
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-upper.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /bg-nav.png HTTP/1.1" 304 -
192.168.57.4 - - [29/Feb/2016:18:14:35 +0800] "GET /asf-logo.png HTTP/1.1" 304 -
--建表語句
create table t_log(
host string,
identity1 string,
identity2 string,
time string,
request string,
referer string,
agent string,) 
row fromat serde 'org.apache.hadoop.hive.serde2.RegexSerDe' 
with serdeproperties(
"input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
)
映射說明:
括號內的內容匹配每一個列,對應關係以下
host                        192.168.57.4
identity1                   -
identity2                   -
time                        29/Feb/2016:18:14:35 +0800
request                     GET
referer                     /bg-upper.png HTTP/1.1
agent                       304

DQL語句

  • SQL 語言大小寫不敏感。

  • SQL 能夠寫在一行或者多行

  • 關鍵字不能被縮寫也不能分行

  • 各子句通常要分行寫,注意tab鍵會致使命令異常

Hive SQL的使用和數據庫SQL基本上是同樣的

主要語法

  • 錶鏈接支持99語法

  • 排序

    sorted by 對deduce數據的數據進行排序

    order by 對所有數據進行排序

  • 分頁

    limit x 展現前x行記錄,與排序組合實現展現最大(小)值

    limit x,y 展現x-y行記錄

  • 組函數

    max min avg sum count 組函數通常與group by組合使用

  • 選擇函數

    nvl(obj,default) 單行選擇函數

    至關於obj==null?default:obj,若obj爲空則取默認值,不然取自身的值

非關係型數據庫DQL

split(column,'-') 將字段分隔爲數組,以某個字符串做爲間隔

explode(split(column,'-)) 將分割的數組展開,但不能直接與普通列同時使用

lateral view explode(split(column,'-)) typeTable as xxx 將列展開成表,再與普通列出如今一行

--數據
nezha js,gx,qq,dm
meirenyu gx,kh,aq
xingjidazhan kh,js
huoyingrenzhe dm,qj,yq,aq
--表
create table t_movie(
name string,type string) 
row format delimited fields terminated by ' ';
--查詢
select name,xxx from t_movie
lateral view explode(split(type,',')) tempTable as xxx;

內置函數

內置運算符

  • 關係運算符

    A = B;A is null;A like B

    返回boolean

  • 算數運算法

    +,-,*,/,%,|,^,~

    適用於數值計算

  • 邏輯運算符

    and,or,not,&&,|,!

    適用於布爾值運算

  • 複雜函數

    • 定義

      • map(k1,v1,k2,v2...)

      • struct(v1,v2,v3...)

      • array(v1,v2,v3)

    • 操做

      • A[n] 數組A的第n個元素,從0開始

      • M['key'] 數組M中key對應的值

      • S.x 結構體S中的x屬性值

內置函數

  • 數字函數

    數值計算相關函數,包括取值,隨機,轉進制,絕對值...

  • 字符串函數

    長度,分割split,鏈接,大小寫,去空格...

  • collection函數

    size(數組/map) 獲取長度

  • 轉型函數

    cast(值 as 目標類型)

  • 日期函數

    與字符串轉換,日期的計算相關

  • 條件函數

    if(boolean,value1,value2)

內置聚合函數UDAF

  • count,sum,avg,min,max;

  • 求方差,差值等;

  • collect_set(col)返回無重複的數據

內置表生成函數UDTF

explode(array) 拆分數組

自定義函數

因爲內置函數不知足咱們的須要,須要自定義函數。(自定義代碼實現對指定的數據進行運算,返回所需的結果,中間可使用java的類庫實現複雜操做)

  • UDF(User-Defined-Function) 一進一出

  • UDAF(User- Defined Aggregation Funcation) 彙集函數,多進一出

  • UDTF(User-Defined Table-Generating Functions)  一進多出(瞭解)

注意:在IDE工具中導入hive依賴jar包 (D:\BigData\課件及軟件\第6階段:Hadoop 離線體系:Hive\軟件\apache-hive-1.2.1-bin\lib)

如下函數均使用臨時函數命令

 

UDF函數

  1. 建立項目,導入hive的jar包,建立java類繼承org.apache.hadoop.hive.ql.exec.UDF

  2. 實現public String evaluate(Object value...)方法,該方法爲重載方法,能夠傳入任意類型數據

  3. 將項目打成jar文件上傳至linux系統

  4. hive客戶端中,清空之前的同名文件,將上傳的文件添加到hive函數庫中

    delete jar /root/xxx.jar

    add jar /root/xxx.jar

  5. 給自定義函數建名稱,指定到對應的自定義java類

    create temporary function xxx as 'com.jay.Xxx'

  6. 使用函數

    select xxx(empno),xxx(emane) from t_emp;

  7. 銷燬函數

    drop temporary function xxx;

自定義函數代碼

package com.jay;
import org.apache.hadoop.hive.ql.exec.UDF;
//自定義UDF函數
public class Myudf extends UDF{
	//單個參數處理
	public String evaluate(String value){
		return value+"xxx";}
	//多參數處理
	public String evaluate(String value1,int value2 ){
		return value1+"-"+value2;}
}

UDAF函數

  • 建立項目,導入hive的jar包,建立java類繼承org.apache.hadoop.hive.ql.exec.UDAF

  • 建立靜態內部類,實現org.apache.hadoop.hive.ql.exec.UDAFEvaluator

    • 重寫init方法,該方法至執行一次

    • boolean iterate(Object) 迭代器

    • Object terminatePartial() 臨時結果輸出

    • boolean merge(Object) 執行合併操做

    • Object terminate() 最終結果輸出

    調用說明(根據需求調用以上方法)

    map過程調用iterate與terminatePartial;

    combiner(map合併)調用merge和terminatePartial

    reduce調用merge與terminate

  • 其餘步驟與HDF相同,調用UDAF會執行MR

import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
public class Myudaf extends UDAF{
	public static class aaa implements UDAFEvaluator{
		//定義一箇中間量,執行所需業務
		private int sum;
		@Override
		public void init() {
			System.out.print("初始化,只執行一次");
		}
		//迭代處理原始數據
		public boolean iterate(String value) {
			if (value != null) 
				sum += value.length();
			return true;
		}
		//臨時輸出
		public int terminatePartial() {
			return sum;}
		//合併
		public boolean merge(int tmpSum) {
			sum += tmpSum;
			return true;}
		//最終輸出
		public String terminate() {
			return "sum:" + sum;}
	}
}

hive優化

在優化中主要關注

Map的數量,reduce數量,文件數量,切片大小

hive中修改配置屬性語句爲:set xxx=值;

理解HSQL的執行

錶鏈接

select u.name, o.orderid from order o join user u on o.uid = u.uid

注:uid做爲key進行MR

表分組及分組函數

select rank, isonline, count (*) from city group by rank , isonline

注:將rank -isonline做爲key

表分組去重

select dealid, count(distinct uid) num from order group by dealid

注:根據dealid執行map以後的分區,根據分區的dealid+去重的uid執行reduce的分組

表多重去重

select dealid, count(distinct uid), count(distinct date) from order group by dealid

方式1:只能在reduce中去重

方式2:實如今map中去重

Map錶鏈接優化

  • 指定大表和小表。減小了全錶鏈接的數量

  • 執行過程:小表節點先執行map,結果載入到hashtable中,各大表節點啓動map並將小表執行結果載入內存,在各大表節點執行map合併,再將數據寫出到reduce處理。

  • select * from a join b join c; 控制a<b<c,使得hive將a視爲b和c的小表,再將b視爲c的小表

避免MR執行

  • select與where默認不會致使MR啓動

    select * from t_emp where id = 8

  • 若select中不須要分區和組函數,可使用hdfs默認的filter進行數據過濾

    hive-site.xml中配置以下信息,屬性爲more時上述狀況默認不啓動MR

    hive.fetch.task.conversion= more不啓動/minimal啓動

  • insert語句必然執行MR操做

map的數量

  • map任務數量過多,節點容易oom(內存溢出)

    map任務數量過少,任務節點少,處理速度慢

  • map數量與切片數量關聯,須要根據具體文件大小和內存設置map數

  • 經過調整切片大小,能夠控制切出的切片數量,進而控制map數量

    mapred.min.split.size 最小切片大小默認1B

    mapred.max.split.size 最大切片大小默認256MB

    上述值用B單位的數字進行設置

reduce數量

數量影響

  • reduce過多產生大量小文件,影響hdfs性能,增長NameNode的負擔

  • reduce過少,單節點壓力大容易oom

系統分配reduce方式,基於如下兩個參數設置

  • hive.exec.reducers.bytes.per.reducer 每一個reduce處理的數據量,默認1G

  • hive.exec.reducers.max 最大reduce數,默認999

  • set mapred.reduce.tasks直接設置reduce個數

系統也會依據桶的數量分配reduce數,使得數據可以存入分桶文件中

只有開啓一個reduce的狀況

  1. 分組函數沒有設置分區

    select pt,count(1) from t_data where pt = ‘2012-07’ [group by pt];

  2. 使用 order by 排序

    order by 會致使整表排序,只能由一個reduce處理

    sorted by則只是對每一個reduce結果排序

行式存儲與列式存儲

行式數據庫:塊內存儲多行數據,一行中有多個不一樣的數據類型,查詢時須要依次進行解析全表數據

列式數據庫:塊內存列的數據,數據按列進行壓縮,因爲列屬性相同,壓縮與解析的格式相同,數據按列處理(列查詢效率高)

1,admin,123456
2,zhangsan,123456
3,lisi,123456

//行式壓縮
1,admin,123456;2,zhangsan,123456;3,lisi,123456
//列式壓縮
1,2   admin,zhangsan 123456,123456
3,lisi,123456


select id ,name from table;  適用於列存儲,使用較多
select * from table where id = 2;  適用於行存儲,大數據中使用較少

 

其餘優化

  • 根據查詢高頻詞建立分區表,減小查詢時數據掃描的範圍

  • 減小使用去重distinct,避免產生數據傾斜

  • JVM重用可使得JVM實例在同一個job中時候使用N次,減小內存開銷

相關文章
相關標籤/搜索