Phoenix(八)二級索引之— —Global Indexing

1. 說明


在HBase中,只有一個單一的按照字典序排序的rowKey索引,當使用rowKey來進行數據查詢的時候速度較快,但是如果不使用rowKey來查詢的話就會使用filter來對全表進行掃描,很大程度上降低了檢索性能。而Phoenix提供了二級索引技術來應對這種使用rowKey之外的條件進行檢索的場景。

Phoenix支持兩種類型的索引技術:Global Indexing和Local Indexing,這兩種索引技術分別適用於不同的業務場景(主要是偏重於讀還是偏重於寫)。下面分別對這兩種索引技術簡單使用一下,具體性能方面沒有進行測試。

以上文字摘自官方文檔

http://phoenix.apache.org/secondary_indexing.html

本篇主要介紹Global Indexing相關技術。

2. Global Indexing


Global indexing targets read heavy,low write uses cases. With global indexes, all the performance penalties for indexes occur at write time. We intercept the data table updates on write (DELETE, UPSERT VALUES and UPSERT SELECT), build the index update and then sent any necessary updates to all interested index tables. At read time, Phoenix will select the index table to use that will produce the fastest query time and directly scan it just like any other HBase table. By default, unless hinted, an index will not be used for a query that references a column that isn’t part of the index.

Global indexing適用於多讀少寫的業務場景。使用Global indexing的話在寫數據的時候會消耗大量開銷,因爲所有對數據表的更新操作(DELETE, UPSERT VALUES and UPSERT SELECT),會引起索引表的更新,而索引表是分佈在不同的數據節點上的,跨節點的數據傳輸帶來了較大的性能消耗。在讀數據的時候Phoenix會選擇索引表來降低查詢消耗的時間。在默認情況下如果想查詢的字段不是索引字段的話索引表不會被使用,也就是說不會帶來查詢速度的提升。


2.1 配置hbase-site.xml


使用Global Indexing的話需要配置hbase-site.xml,在HBase集羣的每個regionserver節點的hbase-site.xml中加入如下配置並重啓HBase集羣

<property>
    <name>hbase.regionserver.wal.codec</name>
    <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>


2.2 創建表


進入phoenix的CLI的界面創建company表。

> create table company(id varchar primary key, name varchar, address varchar);

這裏寫圖片描述

查看company表索引

> !indexes company

這裏寫圖片描述


2.3 創建索引


對company表的name字段創建索引,索引名爲my_index。

> create index my_index on company(name);

查看當前所有表會發現多一張MY_INDEX索引表,查詢該表數據。

> !tables
> select * from my_index;

這裏寫圖片描述

該表中會有2個字段,其中:ID是自動創建的,其實就是HBase中的主鍵RowKey,0:NAME是我們剛剛手動創建的。


2.4 插入數據


在company表中添加測試數據。

> upsert into company(id, name, address) values('001', 'dimensoft', 'nanjing');


2.5 查詢數據


查詢company表數據

> select name,address from company where name='dimensoft';

這裏寫圖片描述

查詢索引表my_index

> select * from my_index;

這裏寫圖片描述

從HBase的CLI界面查看索引表MY_INDEX

> scan 'MY_INDEX'

這裏寫圖片描述

2個索引字段NAME和ID的值被合併爲索引表MY_INDEX的rowKey,\x000是十六進制表示,轉換爲字符串是空格。

高能預警:

> select name,address from company where name='dimensoft';

這樣的查詢語句是不會用到索引表的

Global mutable index will not be used unless all of the columns referenced in the query are contained in the index.

name字段雖然是索引字段但是address字段並不是索引字段!也就是說需要查詢出來的字段必須都是索引字段如:

> select name from company where name='dimensoft';

如果希望使用索引表進行查詢的話可以使用以下三種方式來解決這個問題:

  • 強制使用索引表

在進行查詢的時候通過sql語句強制使用索引查詢。

> SELECT /*+ INDEX(company my_index) */ name,address FROM company WHERE name = 'dimensoft';

This will cause each data row to be retrieved when the index is traversed to find the missing address column value. This hint should only be used if you know that the index has good selective (i.e. a small number of table rows have a value of ‘dimensoft’ in this example), as otherwise you’ll get better performance by the default behavior of doing a full table scan.

這樣的查詢語句會導致二次檢索數據表,第一次檢索是去索引表中查找符合name爲dimensoft的數據,這時候發現address字段並不在索引字段中,會去company表中第二次掃描,因此只有當用戶明確知道符合檢索條件的數據較少的時候才適合使用,否則會造成全表掃描,對性能影響較大。

  • 創建covered index

創建索引的時候指定一個covered字段,先刪除my_index索引

> drop index my_index on company;

創建covered index

> create index my_index on company(name) include(address);

This will cause the address column value to be copied into the index and kept in synch as it changes. This will obviously increase the size of the index.

使用這種方式創建的所有會導致address字段的值被拷貝到索引中,缺點就是會導致索引表大小有一定的增加。

查詢索引表my_index數據。

> select * from my_index;

這裏寫圖片描述

這裏的數據是自動同步過來的,可以發現address字段的值也被存儲了。

從HBase的CLI中查看MY_INDEX表數據會發現比不使用include的時候多了一行數值,並且裏面包含了address字段的值。

> scan 'MY_INDEX'

這裏寫圖片描述

這個時候就再使用下面的查詢語句就會使用到索引來進行查詢了。

> select name,address from company where name='dimensoft';
  • 使用Local Indexing創建索引

與Global Indexing不同,當使用Local Indexing的時候即使查詢的所有字段都不在索引字段中時也會用到索引進行查詢(這是由Local Indexing自動完成的)。這部分內容會放到後一篇文章詳細介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章