MLSQL对Z-Odering索引的支持(预览)

上篇博文Z-Ordering索引加速大数据查询我们 阐述了Z-Ordering索引的基本实现逻辑。这篇我们看看MLSQL是如何集成并且提供优秀的交互能力的。

构建索引

我们先构造一个测试数据:

set data='''
{"status":1,"mlsql_user_id":123,"created_at":100}
{"status":2,"mlsql_user_id":121,"created_at":101}
{"status":3,"mlsql_user_id":119,"created_at":102}
{"status":4,"mlsql_user_id":225,"created_at":103}
{"status":4,"mlsql_user_id":173,"created_at":104}
{"status":5,"mlsql_user_id":8,"created_at":105}
{"status":4,"mlsql_user_id":4,"created_at":106}
{"status":4,"mlsql_user_id":1,"created_at":107}
{"status":4,"mlsql_user_id":2,"created_at":108}
{"status":4,"mlsql_user_id":2,"created_at":108}
{"status":4,"mlsql_user_id":2,"created_at":108}
{"status":4,"mlsql_user_id":2,"created_at":108}
{"status":4,"mlsql_user_id":2,"created_at":108}
''';
load jsonStr.`data` as dataTable;

将dataTable加上Z-Ordering索引,然后保存成delta表:

train dataTable as ZOrdering.`` 
where indexFields="status,mlsql_user_id,created_at"
and fileNum="5"
as newDF;

save overwrite newDF as delta.`public.dataTable`;

使用ZOrdering ET,通过参数indexFields指定需要构建索引的字段,然后通过fileNum指定分区数。 最后通过save语法进行保存结果即可。

此时newDF其实相比dataTable新增了一个字段__mlsql_indexer_zordering_8e8e3948573bfcb5c7267884fa389375. 该字段为二进制格式。

如果现实在界面上,大概是这么个样子:

查询

我们可以使用Load语法加载delta表:

load delta.`public.dataTable` as delta_mlsql_job;

查询分两种,隐式使用索引和显示使用索引。

隐式使用索引,只要在对Engine进行Rest请求时,新增一个参数enableQueryWithIndexer,并且设置为true即可。这个时候系统会对查询尝试进行query改写从而实现利用索引加速。该参数默认为false,因为索引种类比较多的情况下,系统会尝试自动选择一个索引,这个过程可能比较耗时。一旦开启,这个时候你执行正常查询如:

load delta.`public.dataTable` as delta_mlsql_job;
select * from delta_mlsql_job where (status=4 and mlsql_user_id=1 ) as output;

系统会自动使用索引加速。

显式使用索引

你如果想显示指定使用什么索引进行查询,可以按如下方式:

load delta.`public.dataTable` as delta_mlsql_job;
select * from delta_mlsql_job where (status=4 and mlsql_user_id=1 ) as newtable1;
predict newtable1 as ZOrdering.``  as newtable2;

我们只需要对最后需要输出的表,使用ZOrdering ET 进行包裹,得到一张新表,这个newtable2在计算时,就已经获得了索引加速。查询结果如下:

还有问题么?

其实有两个地方,有部分强迫症的用户可能会不爽,

第一个,你给我加了一个索引列,能不能给我隐藏了,让我看不到? 第二个,我想看看这个索引实际是啥样子的,但是二进制形式,我可咋看。

第一个后续我们提供机制,帮助用户自动过滤掉,不会显示给用户看,不过我们还在思考如何以最方便的方式让用户自己决定是不是显示索引字段。

第二个,利用MLSQL灵活强大的UDF,可以很容易对二进制进行观察。比如我定义一个函数,将每个byte都转化为一个无符号的int类型数字,然后使用该函数进行查看:

register ScriptUDF.`` as toUnsigned where 
lang="scala"
and code='''
def apply(item:Array[Byte])={
   item.map(b=>b & 0xFF).toList
}'''
and udfType="udf";

select *,toUnsigned(__mlsql_indexer_zordering_8e8e3948573bfcb5c7267884fa389375) from delta_mlsql_job  as output;

这样就可以很方便的看清楚了。当然你如果希望dig更多,就发挥自己的才智吧。

总结

MLSQL 未来会以相同的方式,提供更多的索引供大家选择和使用。我们计划后续很快会推出 schema less字段的过滤查询加速索引(比如希望对Json文本字段里的属性进行过滤)。 上面的示例在mlsql-engine_2.4-2.1.0-SNAPSHOT.tar.gz 版本中可尝鲜。

results matching ""

    No results matching ""