原生索引问题

  • nebula 版本:2.5.0
  • 部署方式(分布式 / 单机 / Docker / DBaaS):单机
  • 是否为线上版本: N

最近在研究NebulaGraph的原生索引,阅读了官网博客文章:分布式图数据库 Nebula Graph 的 Index 实践
自己在测试时遇到了一个问题

点标签: dhhm
点属性: vId,city,operator,vId是点的ID值
索引: index1 on dhhm(vId) 、 index2 on dhhm(city) ,不对 operator 建立索引

查询语句1:lookup on dhhm where dhhm.vId == “DHHM_13500000001” and dhhm.city == “重庆” | limit 10;
查询语句2:lookup on dhhm where dhhm.city == “重庆” and dhhm.vId == “DHHM_13500000001” | limit 10;
查询语句3:lookup on dhhm where dhhm.vId == “DHHM_13500000001” and dhhm.operator == “联通” | limit 10;
查询语句1和查询语句2耗时5秒,执行语句3耗时0.01秒,指定两个都建立了索引的字段反而更慢
分析发现执行语句1和执行语句2都是基于 city做索引扫描,会匹配上大量数据,然后再根据vId过滤,而vId是唯一的,只会匹配出一条,由此导致查询语句1和查询语句2慢

问题:index1 的 indexId 为 index_6,index2 的indexId 为 index_7,在选择索引进行匹配的时候按照什么规则选择的呢?

1 个赞

非常好的问题

我的初步了解,现在是 RBO(基于规则的优化),基于规则只能有一部分认为预制的容易看出来有效的选择方式优化规则(比如点查优先于范围),另外因为原生索引是 prefix 左匹配,所以多条件的情况下,如果没有复合索引(index_comp(vld, city))的话,只能是一个索引里扫。
像您这个例子里,应该是 vld 的 cost 比较小,但是因为还没有 CBO(基于预估的effort cost 优化),所以选择了不优化的索引方式。

在 CBO 之前(如果不是发现了通用的新的可以增加的 RBO rule的话)这个情况可能不太好缓解,如果业务上查询都是两个条件的,您可以试着建立 index_comp(vld, city) 取舍一下,并且在写语句条件的时候把 vld 排在前边看看(我还没确定有了复合索引顺序是否影响)?

等研发同学纠错、给出补充哈~

建立复合索引 index_comp(vld, city) 后,查询语句1和查询语句2都可以很快出结果,查询时指定索引字段顺序没有影响,在分析时发现都使用到了复合索引,都是先查询vId,再查询city,应是做了优化
删除复合索引,重建复合索引index_comp(city,vld) ,查询语句1和查询语句2在进行查询时都是先查city,再查vId,结果也是很快,因为两个字段都去查了索引,而不是之前查city索引,然后对vId过滤

所以这种情况建议建立复合索引

1 个赞

感谢你的尝试和结论:+1:t2:

我最近也遇到索引问题。全文索引走es很快反悔了,但是内部还进行了大量数据拉取、索引扫描和过滤花费了好长时间。同一个机器配置下,2.0版本操作几十毫秒,2.5的版本就得三四秒才能完成。不升级有一堆bug,升级了也有这些问题。 :joy:

1 个赞

此外,在不建立复合索引的情况下,建立索引时指定的字段长度,比如index1 on dhhm(vId(20)) 、 index2 on dhhm(city(10)),对于查询结果并没有影响,应是优化没有考虑这个因素
在对索引建立的先后顺序进行调整后,即之前是先建立了index2 on dhhm(city(10)),再建立index1 on dhhm(vId(20)) ,现在先建立index1 on dhhm(vId(20)) ,再建立index2 on dhhm(city(10)),查询时,查询语句1和查询语句2都使用了vId做索引,结果响应很快,所以在选择索引时,索引创建的时间是重要参考因素,创建时间早的优先选择

2 个赞

在那个 topic 回您了哈,感觉之前和 bright sky 碰过,2.5 的修改没有造成 es 数据变大的,只有变小的,他怀疑是对应 2.5上 es 集群的问题,您能去排除一下么?