两条基本相同的SQL:
-
SELECT SEQ_ID,SHOW_DATE,EMAIL,TIME_SPEND,CAM_SITE,TOKEN_EARNED,REVENUE,TIPS_SENT,TOY
-
FROM T_EXTENSION_SHOW
WHERE SHOW_DATE=
'2018-11-26'
-
AND SEQ_ID
IN(
2999909,
2999908,
2999907,
2999906,
2999905,
-
2999904,
2999903,
2999902,
2999901,
2999900);
没有查询出数据:
单独只查询2999900,可以查出数据。
-
SELECT SEQ_ID,SHOW_DATE,EMAIL,TIME_SPEND,CAM_SITE,TOKEN_EARNED,REVENUE,TIPS_SENT,TOY
-
FROM T_EXTENSION_SHOW
WHERE SHOW_DATE=
'2018-11-26'
AND SEQ_ID
IN(
2999900);
-
SELECT SEQ_ID,SHOW_DATE,EMAIL,TIME_SPEND,CAM_SITE,TOKEN_EARNED,REVENUE,TIPS_SENT,TOY
-
FROM T_EXTENSION_SHOW
WHERE SHOW_DATE=
'2018-11-26'
-
AND SEQ_ID
IN(
2999909,
2999908,
2999907,
2999906,
2999905,
-
2999904,
2999903,
2999902,
2999901);
IN条件中,删除了2999900,其他完全相同。竟然查询数据了???Phoenix的bug应该没错了。
查看执行计划,语句走的是IDX_T_EXTENSION_SHOW_SEQ_ID二级索引。
接着我们查看这个二级索引??科学计数法
于是乎我把最开始的查询SQL改为:
SELECT SEQ_ID,SHOW_DATE,EMAIL,TIME_SPEND,CAM_SITE,TOKEN_EARNED,REVENUE,TIPS_SENT,TOY FROM T_EXTENSION_SHOW WHERE SHOW_DATE='2018-11-26' AND SEQ_ID IN(2999909, 2999908, 2999907, 2999906, 2999905, 2999904, 2999903, 2999902, 2999901, 2999900);
SELECT SEQ_ID,SHOW_DATE,EMAIL,TIME_SPEND,CAM_SITE,TOKEN_EARNED,REVENUE,TIPS_SENT,TOY FROM T_EXTENSION_SHOW WHERE SHOW_DATE='2018-11-26' AND SEQ_ID IN(2999909, 2999908, 2999907, 2999906, 2999905, 2999904, 2999903, 2999902, 2999901, 2.99999E+6);
终于查出了数据:
那问题来了,怎么会出现科学计数法?
原表中的SEQ_ID字段是BIGINT类型:
再看看二级索引表结构,Why??? 竟然是DECIMAL类型。这是怎么回事。
创建索引SQL:
CREATE INDEX IDX_T_EXTENSION_SHOW_SEQ_ID ON T_EXTENSION_SHOW(SHOW_DATE,SEQ_ID DESC) INCLUDE(TIME_SPEND,CAM_SITE,TOKEN_EARNED,REVENUE,TIPS_SENT,TOY);
创建二级索引时,Phoenix竟然给我改了类型。SEQ_ID 字段原表中BIGINT,二级索引表中改为了DECIMAL!!!
有谁遇到相同情况吗?
结论:
phoenix 5.0当前版本,如果是BIGINT、或者UNSIGNED_LONG这种非主键字段。
为这种字段,建立二级索引时,那么二级索引的这个字段类型将自动转为DECIMAL类型。就是这么神奇。这将会导致,使用in进行多个条件查询时失效。如果in只有一个条件比如 where id in(2999900) 或者 where id=2999900 这样是不会受到科学计数法影响的。如果是where id in(2999900, 2999901) ,那么将查不到数据(DEGENERATE SCAN OVER)。
解决方法:
1、使用等于号,加上union all关联数据。(太麻烦,不推荐。)
2、改二级索引表的字段类型,将decimal改为bigint。(试过后,失败告终。不用考虑)。
3、将seq_id建表时,设置为not null,并属于联合主键。(从根本上,解决问题。)
SEQ_ID BIGINT NOT NULL, -- 序列ID
CONSTRAINT PK PRIMARY KEY (SHOW_DATE, EMAIL, SEQ_ID)
这样建立二级索引,索引表中的seq_id字段,还是保持bigint类型。没有发生变化。
猜测,phoenix对主键的字段类型要求更加严格~。希望后续官方能修复这个"bug"。