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

本文分享自华为云社区《查询语句写了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. ubantu14.04搜狗拼音安装

    1. 先卸载fcitx: sudo apt-get purge fcitx*2. 安装fcitx和libssh2-1: sudo apt-get install fcitx 和 sudo apt-ge ...

  2. ubantu系统之 在桌面添加应用快捷方式

    1. 首先在终端使用命令:sudo nautilus 这个命令会让你用root权限打开文件管理器,输入这个命令然后输入密码确认之后会弹出一个目录窗口;2. 然后我们就要找到目录:/usr/share/ ...

  3. CCF201509-2日期计算

    问题描述 给定一个年份y和一个整数d,问这一年的第d天是几月几日? 注意闰年的2月有29天.满足下面条件之一的是闰年: 1) 年份是4的整数倍,而且不是100的整数倍: 2) 年份是400的整数倍. ...

  4. h5页面跳转小程序

    2020年以前, 只能通过 web-view内嵌h5跳转小程序,现在  可以直接跳了!!!!!!  官方文档:https://developers.weixin.qq.com/doc/offiacco ...

  5. js中的undefined

    undefined,一个特殊值,通常用于指示变量尚未赋值,是一个JavaScript的 原始数据类型 . 如果后台返回前台数据为空(无数据),那么用该对象获取其中的属性会显示undefined. 如果 ...

  6. GO语言学习——基本数据类型——整型、浮点型、复数、布尔值、fmt占位符

    基本数据类型 整型 整型分为以下两个大类: 按长度分为:int8.int16.int32.int64 对应的无符号整型:uint8.uint16.uint32.uint64 其中,uint8就是我们熟 ...

  7. 3种方法改变this的指向

    <body>     <div style="width: 200px;height: 200px;hotpink;"></div>     & ...

  8. Intellij IDEA 2022 正式发布,这些功能真不错

    Intellij IDEA 2022 正式发布了,作为正版用户,胖哥赶紧更新了一波,好家伙!这几个功能确实很香啊.新版更新的东西真不少,不愧是一个大版本更新. 依赖分析 IDEA的依赖检查.依赖冲突解 ...

  9. Python实现双X轴双Y轴绘图

    诈尸人口回归.这一年忙着灌水忙到头都掉了,最近在女朋友的提醒下终于想起来博客的账号密码,正好今天灌水的时候需要画一个双X轴双Y轴的图,研究了两小时终于用Py实现了.找资料的过程中没有发现有系统的文章, ...

  10. Apache Doris ODBC外表之Postgresql使用指南

    Apache Doris 社区 2022 年的总体规划,包括待开展或已开展.以及已完成但需要持续优化的功能.文档.社区建设等多方面,我们期待有更多的小伙伴参与进来讨论.同时也希望多多关注Doris,给 ...