phoenix查询hbase ,想要走rowkey查询却成了走索引

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haoshuai2015/article/details/79963716

背景: 这是实际项目中遇到的实例,主要涉及到rowkey查询,索引查询 以及主键primary key。问题是在sql使用order by 查询 时遇到的,以下为个人浅见,仅供参考。

内容:

     Hbase中存在数据表如下:

CREATE TABLE IF NOT EXISTS Test.AppLog ( 
 UserId INTEGER NOT NULL,
 Number INTEGER NOT NULL,
 AcType INTEGER NOT NULL,
 Upserttime DATE NOT NULL,
 UploadCount INTEGER NULL,
 Token VARCHAR(50)  NULL,
 IsSuccess BOOLEAN NULL,
 Data VARCHAR NULL,
 ErrorMessage VARCHAR NULL,
 CONSTRAINT pk_TestAppLog
 PRIMARY KEY (UserId, Number, AcType, Upserttime)
 ) default_column_family='apl', SALT_BUCKETS=8;

建立表相应的索引

CREATE INDEX IF NOT EXISTS idx_TestAppLog_Upserttime ON Test.AppLog (Upserttime) 
INCLUDE (UserId, Number, AcType) SALT_BUCKETS=8;

针对上表,当我们使用select * 查询时,是走主键(rowkey)查询的。

eg:

explain select * from Test.AppLog
where userid = 10 and AcType = 2
order by Upserttime desc limit 100;

结果如下:    

 CLIENT 3-CHUNK 4368912 ROWS 943718514 BYTES PARALLEL 3-WAY RANGE SCAN OVER TEST:APPLOG [0,10] - [2,10]  |
|     SERVER FILTER BY ACTYPE = 2                                                                                   |
|     SERVER TOP 100 ROWS SORTED BY [UPSERTTIME DESC]                                                               |
| CLIENT MERGE SORT 

当我们查询具体字段(注意字段变量与索引字段的对应关系)时,如下,却是走了索引查询。

eg:

explain select UserId,AcType,Upserttime from Test.AppLog
where userid = 10 and AcType= 2
order by Upserttime desc limit 100;

结果如下:

CLIENT 8-CHUNK 0 ROWS 0 BYTES PARALLEL 8-WAY REVERSE RANGE SCAN OVER TEST:IDX_TESTAPPLOG_UPSERTTIME [0] - [7] |
|     SERVER FILTER BY FIRST KEY ONLY AND ("USERID" = 10 AND "ACTYPE" = 2)                                            |
|     SERVER 100 ROW LIMIT                                                                                            |
| CLIENT MERGE SORT                                                                                                   |
| CLIENT 100 ROW LIMIT

疑问 : 

 select  * 是走rowkey,select 某些特定字段却是走索引;  当我们去掉 order by的时候,select  * 同样是走rowkey,select 任意字段亦是走rowkey。

原因以及解决办法:

造成该种情况的原因是order by 中的字段(上例中的Upserttime)既是primary key(主键),又是indexes(索引)。

当select 中的字段正好和索引包含的(include)字段一致时,此时phoenix默认会走索引查询。

我们select的字段不与索引包含字段完全一致就不会造成这种情况;因为primary key是主要的,因此可以在建索引时不添加所有字段; 总之 要查询的字段与索引包含字段并不重合 或者没有使用order by 索引字段 即可。

2018-04-16


阅读更多

没有更多推荐了,返回首页