四问复合索引,让你的数据查询速度飞起
本文分享自华为云社区 《华为云GES持久化图数据库复合索引介绍》,作者:村头树下。
本文章主要介绍索引的作用,以及如何实现这种功能,希望可以帮助理解索引的作用以及如何使用索引
1. 什么是复合索引
复合索引是用户手动建立的用于加速查询的一类额外数据。详细参数可以参考规格文档
https://support.huaweicloud.com/api-ges/ges_03_0454.html
2. 复合索引能做什么
复合索引有两类。一是label索引,用于加速label的扫描。二是属性索引,用于加速属性过滤。
这里列举了一些常用接口(语句)与索引的关系
api接口 | 索引加速方式 |
---|---|
summary | 扫描label索引,统计各label点边数目 |
match (n:user) return count(*) | 扫描点label索引,统计label为user的点数目 |
match ()-[r:label]-() return count® | 扫描边label索引,统计指定label点数目 |
match (n:user) return n limit 1 | 通过点label索引快速寻找label为user的点 |
match (n:user) where n.age > 10 return n limit 1 | 仅有label索引时扫描label索引,寻找user的点,然后进行属性过滤。当存在age属性索引时直接使用属性索引定位到目标点 |
match (n:user) where n.age in [1, 10] return n limit 1 | 同上 |
3. 无索引时如何查询
首先了解无索引的情况下,查询的逻辑,才可以理解索引在此基础上做了什么使得查询能够加速。查询逻辑主要与两个方面有关:数据结构,以及数据访问方式,以及查询场景。
a) 原始点结构
持久化版本所有数据都是以KV(键值对)的方式存储在分布式KV数据库中,在没有建立索引的时候,数据库中仅有原始点边KV。以点数据结构为例:
Key:
Value:
key的开始部分为kVType,这是所有数据都会存在的固定前缀,用以区分不同类型的数据。然后是Vid是全局唯一点id。Labelid是标识label的内置编码。Value则是属性的数据。
b) 数据访问方式
所有的图数据的查询最终都是依托于KV数据库的访问。常用的访问KV数据的方式有两种:
- 精确查询接口,指定完整的key查询value
- 前缀查询接口,仅指定key的前缀部分,查询所有key的前缀匹配的KV数据对。前缀查相对来说会更加频繁的使用。一个场景可能会需要多次前缀查,而前缀查的次数越多,结果越多,相应的此场景响应速度就越慢。前缀查结果大小直接与前缀的长度有关,前缀越长或者越精确,那么前缀查的结果越少。需要的计算量也越少。相应速度就会越快。
c) 查询场景:
常见查询场景的对应的kv层接口调用:
场景 | KV接口及调用次数 | 查询速度 | 对应Cypher语句 |
---|---|---|---|
指定id过滤 | 前缀查 * 1 | 快,由于KVType和Vid已知,可以拼出前缀,同时一个id一般不会有太多label,前缀查的结果不会特别多。 | match(n) where id(n)=‘0’ return n |
指定label过滤 | 前缀查 n + 过滤 m
| 慢, 由于不知道Vid,所以只能先拼出只有KVType的前缀,然后前缀查出所有点,再逐个过滤Label,点数据较多时,会有多次前缀查,分批获取再过滤。 | match(n:Label) return n |
指定label+属性过滤 | 前缀查 n + 过滤 m
| 慢, 查询前缀为KvType,遍历全图点,先进行Label过滤,再进行属性过滤 | match (n:Label) where n.prop=‘xx’ return n |
指定属性过滤 | 前缀查 n + 过滤 m
| 非常慢, 查询前缀为KvType,遍历全图点,全部进行属性过滤 | match (n) where n.prop=‘xx’ return n |
可见,除了指定id的查询,其他所有查询均非常慢。这些查询都需要进行全图点扫描加过滤的方式来获取结果。这与查询出来的结果数目无关。对于较大的图来说,这样的查询代价是十分巨大的。
4. 复合索引如何加速
查询慢的场景无外乎两种场景,label查询或者属性查询。在没有索引的情况下,这两种查询都是建立在全局点扫描的基础上,进行过滤。当有效数据占比越低(例如全局点1w,目标点仅有1个),这种扫描方式就越显得不划算。
对于这两种场景,我们可以建立对应的索引。索引本身也是KV数据。所以其key的布局就决定了其功能。
1.对于label过滤场景,索引的key的格式为:
对于每一个点,都会有一条对应的Label索引KV。
当需要过滤特定Label时,可以拼出KVType+Label的前缀,利用kv数据底座的前缀查接口,就能直接将所有符合条件的点过滤出来。
2. 对于属性过滤的场景,索引的key格式为:
属性索引只针对个别过滤较为频繁的属性而建立。所以也只会对包含此属性的点才会生成属性索引kv。相比于Label索引这里只是多了一个property字段。此字段填的是Vid对应点的属性的值。需要注意的是,property字段并不包含全部的点属性,仅仅是待过滤属性的值。
当进行属性查询时,由于知道目标值(例如where n.prop=1,目标值就是1)。直接拼出KVTypr+Label+Property,调用前缀查询接口。即可查出所有符合条件的点。
当利用索引查出匹配的索引KV之后,就可以很方便的拿到对应的VId。然后根据此Vid,就能快速查询到这个点的属性,或者邻居等信息。
5. 索引建立的若干建议
索引并不是没有代价的,虽然它能加速查询,但是会降低写操作的性能,以及耗费更多的磁盘空间。所以建立索引之前需要考虑是不是必要的。这可以从数据区分度,数据大小,以及访问频率三个方面来评估。
- 数据区分度:对于属性索引建议在过滤性好的属性上建立。值分布较为分散,比较适合建立。例如身份证号,手机号。但是对于性别这种属性,就不建议为此建立。对于label索引,如果图里面只有一个label,那么建label索引其实也是没有什么必要的,但是大部分情况,label索引都是必要的。
- 数据大小:这主要是针对属性索引来说的,在已经有Label索引的前提下,如果某个label下的点边数目很少,即使扫描所有label代价也不高,这时候没有必要再为其建立属性索引。
- 访问频率:这一点很好理解,只对频繁在where子句中出现的属性建立索引。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
GNU 和自由软件运动四十周年
自由软件基金会 (FSF) 发表文章庆祝 GNU 和自由软件运动四十年。 1983 年 9 月 27 日,计算机科学家 Richard Matthew Stallman(简称 RMS)宣布开发类 Unix 自由软件操作系统的「GNU计划」,并借此发起自由软件运动,GNU 名字代表 GNU's not Unix。 ▲「GNU 计划」标志 四十年后的今天,GNU 和自由软件比以往任何时候都重要,虽然软件已经深入到我们的日常生活,但绝大多数用户无法完全控制它。 自由软件的定义最初由 RMS 本人制定。自由软件的初衷是尊重用户的自由,并且尊重整个社区。 粗略来讲,一个软件如果是自由软件,这意味着用户可以自由地运行、拷贝、分发、学习、修改并改进该软件。因此,「自由软件 (Free Software)」中的"free"是关乎自由的问题,与价格无关,软件如何定价并不影响它是否被归类为自由软件。 具体来说,自由软件的用户拥有四项基本自由: (0)自由运行软件 (1)自由学习和修改软件源代码 (2)自由发布软件拷贝 (3)自由发布修改后的软件版本 GNU 是唯一专门为捍卫用户自由而开发的操作系统,四十年...
- 下一篇
代码检查过程中为什么需要涉及到编译呢?
本文分享自华为云社区《代码检查过程中为什么需要涉及到编译呢?》,作者:gentle_zhou。 随着大家对软件安全越来越重视,在编码阶段针对源码安全的保障也被各行各业企业研发测试运维团队与个人开发者越来越频繁的被提及,其中静态代码检查SAST工具尤为突出。 SAST代码检查服务作为一款可以对源码进行质量(包括风格)、安全、规范等方面进行检查的工具,它可以检测出代码中存在的缺陷与风险。而随着大家对工具深入的使用,很多小伙伴在使用过程中产生了困惑,不是说好只针对源码进行检查吗?为什么还会涉及编译?为什么在我本地编译成功,放到云端环境就说编译失败了呢? 本文尝试针对上述这些问题一一进行解释,让小伙伴们了解清楚其中的过程与原理。 1、不是说好只针对源码进行检查吗?为什么还会涉及编译? 一般来说是的,SAST静态代码检查是一种静态应用程序安全测试技术,通常是在代码编译之前进行的;也就是说,SAST工具并不是强制需要执行或运行代码才可以使用,针对源码本身就可以去分析代码的语法、结构、逻辑等。 但是,这并不意味着SAST工具就与编译无关了;事实上,SAST工具在必要的时候,也需要借助编译构建工具来将...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS关闭SELinux安全模块
- Hadoop3单机部署,实现最简伪集群
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题