以前的文章《更高的壓縮比,更好的性能–使用ORC文件格式優化Hive》中介紹了Hive的ORC文件格式,它不但有着很高的壓縮比,節省存儲和計算資源以外,還經過一個內置的輕量級索引,提高查詢的性能。這個內置的輕量級索引,就是下面所說的Row Group Index。性能優化
其實ORC支持的索引不止這一種,還有一種BloomFilter索引,二者結合起來,更加提高了Hive中基於ORC的查詢性能。數據結構
說明一下:本文使用Hive2.0.0 + hadoop-2.3.0-cdh5.0.0做爲測試環境。表lxw1234_text爲text格式保存,總記錄數爲12000920。ide
由以前的文章知道,一個ORC文件包含一個或多個stripes(groups of row data),每一個stripe中包含了每一個column的min/max值的索引數據,當查詢中有<,>,=的操做時,會根據min/max值,跳過掃描不包含的stripes。oop
而其中爲每一個stripe創建的包含min/max值的索引,就稱爲Row Group Index,也叫min-max Index,或者Storage Index。在創建ORC格式表時,指定表參數’orc.create.index’=’true’以後,便會創建Row Group Index,須要注意的是,爲了使Row Group Index有效利用,向表中加載數據時,必須對須要使用索引的字段進行排序,不然,min/max會失去意義。另外,這種索引一般用於數值型字段的查詢過濾優化上。性能
看下面的例子:測試
直接執行下面的查詢(未使用索引):大數據
很明顯,掃描了全部記錄。再使用索引查詢:優化
能夠看到,只掃描了部分記錄,即根據Row Group Index中的min/max跳過了WHERE條件中不包含的stripes,索引有效果。spa
假若有下面的查詢:htm
執行的過程大概是這樣的:
先根據Row Group Index中的min/max,判斷哪些stripes/file包含在內,接着逐行掃描,過濾pcid IN (‘0005E26F0DCCDB56F9041C’,’A’)的記錄。
能夠看到,沒有全表掃描,跳過了一部分stripes。這樣看來,若是where後面的id範圍很大,徹底可能會包含全部的文件,再根據pcid過濾時候,又至關於全表掃描了。
對於這種查詢場景的優化策略,就是下面的BloomFilter索引。
以前有篇文章《大數據去重統計之BloomFilter》,介紹過BloomFilter的原理和Java版的例子。Hive的ORC中基於此,提供了BloomFilter索引,用於性能優化。
在建表時候,經過表參數」orc.bloom.filter.columns」=」pcid」來指定爲那些字段創建BloomFilter索引,這樣,在生成數據的時候,會在每一個stripe中,爲該字段創建BloomFilter的數據結構,當查詢條件中包含對該字段的=號過濾時候,先從BloomFilter中獲取如下是否包含該值,若是不包含,則跳過該stripe.
看下面的建表語句,爲pcid字段創建BloomFilter索引:
而後執行上面的查詢:
經過Row Group Index和Bloom Filter Index的雙重索引優化,這條語句最終執行,只掃描了60000條記錄,大大節省了MapTask的執行時間和資源。
以前的文章《更高的壓縮比,更好的性能–使用ORC文件格式優化Hive》中介紹了Hive的ORC文件格式,它不但有着很高的壓縮比,節省存儲和計算資源以外,還經過一個內置的輕量級索引,提高查詢的性能。這個內置的輕量級索引,就是下面所說的Row Group Index。
其實ORC支持的索引不止這一種,還有一種BloomFilter索引,二者結合起來,更加提高了Hive中基於ORC的查詢性能。
說明一下:本文使用Hive2.0.0 + hadoop-2.3.0-cdh5.0.0做爲測試環境。表lxw1234_text爲text格式保存,總記錄數爲12000920。
由以前的文章知道,一個ORC文件包含一個或多個stripes(groups of row data),每一個stripe中包含了每一個column的min/max值的索引數據,當查詢中有<,>,=的操做時,會根據min/max值,跳過掃描不包含的stripes。
而其中爲每一個stripe創建的包含min/max值的索引,就稱爲Row Group Index,也叫min-max Index,或者Storage Index。在創建ORC格式表時,指定表參數’orc.create.index’=’true’以後,便會創建Row Group Index,須要注意的是,爲了使Row Group Index有效利用,向表中加載數據時,必須對須要使用索引的字段進行排序,不然,min/max會失去意義。另外,這種索引一般用於數值型字段的查詢過濾優化上。
看下面的例子:
直接執行下面的查詢(未使用索引):
很明顯,掃描了全部記錄。再使用索引查詢:
能夠看到,只掃描了部分記錄,即根據Row Group Index中的min/max跳過了WHERE條件中不包含的stripes,索引有效果。
假若有下面的查詢:
執行的過程大概是這樣的:
先根據Row Group Index中的min/max,判斷哪些stripes/file包含在內,接着逐行掃描,過濾pcid IN (‘0005E26F0DCCDB56F9041C’,’A’)的記錄。
能夠看到,沒有全表掃描,跳過了一部分stripes。這樣看來,若是where後面的id範圍很大,徹底可能會包含全部的文件,再根據pcid過濾時候,又至關於全表掃描了。
對於這種查詢場景的優化策略,就是下面的BloomFilter索引。
以前有篇文章《大數據去重統計之BloomFilter》,介紹過BloomFilter的原理和Java版的例子。Hive的ORC中基於此,提供了BloomFilter索引,用於性能優化。
在建表時候,經過表參數」orc.bloom.filter.columns」=」pcid」來指定爲那些字段創建BloomFilter索引,這樣,在生成數據的時候,會在每一個stripe中,爲該字段創建BloomFilter的數據結構,當查詢條件中包含對該字段的=號過濾時候,先從BloomFilter中獲取如下是否包含該值,若是不包含,則跳過該stripe.
看下面的建表語句,爲pcid字段創建BloomFilter索引:
而後執行上面的查詢:
經過Row Group Index和Bloom Filter Index的雙重索引優化,這條語句最終執行,只掃描了60000條記錄,大大節省了MapTask的執行時間和資源。