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

本文分享自华为云社区《查询语句写了limit 1,为什么依然很慢? 记一次图引擎GES cypher慢查询的定位分析》,作者: 蜉蝣与海。

问题背景

最近使用华为图引擎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 10至limit 1,结果依旧很慢。

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

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

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

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

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

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

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

既然分析清楚了原因,那么只要通过改写cypher语句,让GES的cypher不优先通过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是支持索引能力的,后续会考虑加入合适的索引,把AllNodesScan和Filter优化为NodeIndexSeek,进一步提升语句执行速度。

总结

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

点击关注,第一时间了解华为云新鲜技术~

查询语句写了limit 1,为什么依然很慢?的更多相关文章

  1. mysql查询语句,通过limit来限制查询的行数。

    mysql查询语句,通过limit来限制查询的行数. 例如: select name from usertb where age > 20 limit 0, 1; //限制从第一条开始,显示1条 ...

  2. SQL查询语句中的 limit offset(转 )

    经常用到在数据库中查询中间几条数据的需求 比如下面的sql语句: ① selete * from testtable limit 2,1; ② selete * from testtable limi ...

  3. sql查询语句如何解析成分页查询?

    我们公司主要mysql存储数据,因此也封装了比较好用mysql通用方法,然后,我们做大量接口,在处理分页查询接口,没有很好分查询方法.sql查询 语句如何解析成“分页查询”和“总统计”两条语句.可能, ...

  4. Mysql查询语句的 where子句、group by子句、having子句、order by子句、limit子句

    Mysql的各个查询语句 一.where子句   语法:select *|字段列表 from 表名 where 表达式.where子句后面往往配合MySQL运算符一起使用(做条件判断) 作用:通过限定 ...

  5. NumberFormatException: Invalid int类型不匹配异常——使用SQL数据库查询语句select * from blacknumber order by _id desc limit ?,20;出现

    异常:类型不匹配 05-06 08:12:38.151: E/AndroidRuntime(14904): java.lang.NumberFormatException: Invalid int: ...

  6. Hibernate三种状态;query查询;ResultTransformer转换为pojo对象;能够将query语句写在xml中;Criteria查询;ProjectionList总和/f分组等函数

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010026901/article/details/24256091 Session操作过程中的po ...

  7. MySQL知识树-查询语句

    在日常的web应用开发过程中,一般会涉及到数据库方面的操作,其中查询又是占绝大部分的.我们不仅要会写查询,最好能系统的学习下与查询相关的知识点,这篇随笔我们就来一起看看MySQL查询知识相关的树是什么 ...

  8. MYSQL查询语句优化

    mysql的性能优化包罗甚广: 索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬件优化,应用层面优化(web服务器,缓存)等等.这里的记录的优化技巧更适用于开发人员,都是从网络上收集和自己整 ...

  9. php面试专题---MYSQL查询语句优化

    php面试专题---MYSQL查询语句优化 一.总结 一句话总结: mysql的性能优化包罗甚广: 索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬件优化,应用层面优化(web服务器,缓存) ...

随机推荐

  1. spring security简介与使用

    目录 spring security 新建一个springboot项目 添加spring security 登录 使用默认用户和随机生成的密码登录 使用yaml文件定义的用户名.密码登录 使用代码中指 ...

  2. Java中读取 .properties 和 .xml 文件

    配置文件内容获取 总结内容 1. Java中为什么要使用配置文件 2. Java中常用的配置文件类型有哪些以及它们的特点 Properties配置文件 XML配置文件 总结 总结内容 1. Java中 ...

  3. FreeRTOS学习记录--任务创建函数详解

    开局一张图.一步一步分析就好. (一)什么是任务? 在多任务系统中,我们按照功能不同,把整个系统分割成一个个独立的,且无法返回的函数,这个函数我们称为任务:任务包含几个属性:任务堆栈,任务函数.任务控 ...

  4. python---输出函数运行时间的装饰器

    """ 装饰器: 不改变原函数的调用方式和函数的前提下, 增加额外的功能, 其本质就是一个闭包 ---输出函数的运行时间 """ impor ...

  5. Spring Boot-@Conditional注解以及衍生注解@ConditionalOnBean

    @Conditional:判断@Conditional指定的条件是否成立,如果成立才会给容器中添加组件,配置类里面的内容才会生效 我们发现有很多的自动配置类,但是这些自动配置类都有指定的条件,必须满足 ...

  6. Docker引擎核心组件

    Docker Engine(Docker引擎)是Docker的核心部分,使用的是客户端-服务器(C/S)架构模式,其主要组成部分如下图所示. 从上图中可以看出,Docker Engine中包含了三个核 ...

  7. maven jar包冲突问题

    之前好端端的项目没做任何改动maven依赖就报红?jar包冲突?不要慌,问题不大. idea file里面点击invalidate Caches/Restart清空项目缓存并重启,ok解决问题.

  8. [个人配置] VSCode Better Comments 扩展配置、高亮注释插件

    在VSCode IDE中,我的代码注释一般都有高亮颜色,那要怎么安装这个插件呢?

  9. CAN总线收发节点设计

    CAN总线收发节点设计 写在前面 这是微机接口的一个项目作业. 这段时间一直在宿舍隔离,没办法进行焊接和测试,但原理和代码已经在学习板子上经过验证. 设计目标 CAN在工业现场大量应用,尤其是汽车工业 ...

  10. 基于Feature Flag的下一代开发模式

    渐进式发布(Progressive Delivery)被认为是持续发布(Continous Delivery)的下一代形态,其专注于增强发布过程控制与降低发布风险,最终提高整体收益.国际科技巨头比如A ...