查询语句写了limit 1,为什么依然很慢? 记一次图引擎GES cypher慢查询的分析与优化

举报
蜉蝣与海 发表于 2022/05/28 11:04:00 2022/05/28
【摘要】 很多时候计算引擎会对语句进行代价估计并调整语句的执行顺序。执行计划是语句如何执行的直观表达。语句如何执行不能只关注语句写法,要想写出符合预期执行顺序的查询语句,还需要关注语句执行计划。

问题背景

 

最近使用华为图引擎GES, 有一条cypher语句携带后缀limit 1,理论上应该很快返回结果,可是跑了很久依旧没有返回,简化后的语句如下:

match(v)-[r1:dependency *1..1]->(node) where node.product_name = "product" match path = (m)-[r:dependency*0..10]-> (v:Material) return path, m,node skip 0 limit 10

调整limit 10limit 1,结果依旧很慢。

华为云图引擎GES官网文档上,发现了对查询语句进行终止的接口:


首先使用listQueries查询出当前cypher语句的queryId,然后把queryId输入killQuery中终止慢查询。

 

问题分析:为什么limit配置为1,依旧长时间无结果?

在华为云图引擎控制台,使用explain打印cypher查询计划,分析慢查询生成原因,简化后的查询计划如图:

可以看到,查询语句的执行和预期有差异。查询语句优先执行了一个Label扫描算子(NodeByLabelScan),对扫描到的每个点按入边方向进行了[r*0..10]这样的10跳操作,而后再从出边方向做了一跳并过滤,这就导致了最坏情况下,需要全图LabelMaterial的点都跳完10跳,才能拿到一条结果。如上图表格所示,在遍历到第一个满足条件的(vi)之前,已经对(v0)(vi)这些点都做了10跳。即使语句末尾写了limit 1,因为始终遍历不到合适的数据,导致了后台的计算引擎一直在做计算。

 估计计算引擎在读取这条语句时,同时看到了v:Material和node.product='xxx'两个过滤条件,而代价估计模型认为v:Material可以获得更低的代价,所以才选择优先执行NodeByLabelScan。

使用语句优化策略对语句进行优化

既然分析清楚了原因,那么只要通过改写cypher语句,让GEScypher不优先通过v:Material做计划即可。这里用到下列两类策略:

with别名策略:使用with为变量安排别名,强制规定语句不同子句的执行顺序

label过滤改写策略:将label过滤条件放在where语句中,并使用labels函数,防止生成NodeByLabelScan的计划

 

使用with别名策略后,语句如下:

match(v0)-[r1:dependency *1..1]->(node) where node.product_name = "product" with v0 as v,node match path = (m)-[r:dependency*0..10]-> (v:Material) return path, m,node skip 0 limit 10

使用label过滤改写策略,语句如下:

match(v)-[r1:dependency *1..1]->(node) where node.product_name = "product" match path = (m)-[r:dependency*0..10]-> (v) where labels(v)='Material' return path, m,node skip 0 limit 10

两种策略混合使用,语句如下:

match(v0)-[r1:dependency *1..1]->(node) where node.product_name = "product" with v0 as v,node match path = (m)-[r:dependency*0..10]-> (v) where labels(v)= " Material" return path, m,node skip 0 limit 10

使用explain将三种查询计划分别打印,如图:


可以看到with别名更有效,生成的计划更符合期望。

使用with别名策略改写cypher语句后,语句运行时间从130秒降到3秒。语句中依旧存在AllNodesScan算子,而华为图引擎GES是支持索引能力的,后续会考虑加入合适的索引,把AllNodesScanFilter优化为NodeIndexSeek,进一步提升语句执行速度。

总结

通过这次分析也可以看出,很多时候计算引擎会对语句进行代价估计并调整语句的执行顺序。执行计划是语句如何执行的直观表达。语句如何执行不能只关注语句写法,要想写出符合预期执行顺序的查询语句,还需要关注语句执行计划。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。