基于Gremlin语言图数据库查询的优化

article/2025/10/7 18:24:26

图谱结构:

其中query标签的结构:

列名类型说明
idinteger唯一主键
classstring类别

a_[a|b|c|d|e|f]标签的结构

列名类型说明
idinteger唯一主键
classstring类别,关联到query的类别
namestring名称

 b_[a|b|c|d|e|f]标签的结构

列名类型说明
idinteger唯一主键
classstring类别,关联到前缀标签a的类别
namestring名称,关联到前缀标签a的名称
indexinteger序号

数据规模:

类别总数:100,每个类别名称数:100,每个类别名称序号总数:10

数据生成脚本:

import pymysql
from itertools import productmydb = pymysql.connect(host="localhost",user="",passwd="",database="test_graph"
)classes, names = 100, 100mycursor = mydb.cursor(pymysql.cursors.DictCursor)
mydb.begin()
mycursor.execute('delete from query;')
mycursor.execute('delete from entity;')
mycursor.execute('delete from relation;')
mycursor.execute('alter table query auto_increment=1')
mycursor.execute('alter table entity auto_increment=1')
mycursor.execute('alter table relation auto_increment=1')
for i in range(classes):mycursor.execute(f'insert into query(class) values({i})')for i, k, name in product(range(classes), 'abcdef', range(names)):mycursor.execute(f"insert into entity(class, `table`, `name`) values({i},'a_{k}', 'name_{name}')")for i, k, name, index in product(range(classes), 'abcdef', range(names), range(10)):mycursor.execute(f"insert into entity(class, `table`, `name`, `index`) values({i},'b_{k}', 'name_{name}', {index})")print('-----------------------------------')
for k in 'abcdef':mycursor.execute(f"insert into relation(h, h_table, r, t, t_table) select query.id, 'query', 'query', entity.id, 'a_{k}'"f" from query, entity where query.class = entity.class and entity.table = 'a_{k}'")for k in 'abcdef':mycursor.execute(f"insert into relation(h, h_table, r, t, t_table) select ea.id, 'a_{k}', 'ab', eb.id, 'b_{k}' "f" from entity ea, entity eb where ea.name = eb.name and ea.class = eb.class and ea.table = 'a_{k}' and eb.table = 'b_{k}'")mydb.commit()
mycursor.close()

 优化方法:

1、简化返回接口

一次不要返回太多内容和太多字段

2、接口分离

查询较慢的部分(例如聚合运算统计数量)可以单独分离成一个接口以提高整体的体验

3、关键字段引入索引

g.V().hasLabel("label").values("name").fold().order(Scope.local).index().unfold().order().by(__.tail(Scope.local, 1)) 

4、并行处理

执行多条语句时可并行处理,如下所示,程序总体执行时间为2s

import asyncio
import timedef r1(a, b):time.sleep(a)return 1 + bdef r2(a):time.sleep(a)return 2 + aasync def run(loop):task1 = loop.run_in_executor(None, r1, 1, 4)task2 = loop.run_in_executor(None, r2, 2)return await task1 + await task2if __name__ == "__main__":loop = asyncio.new_event_loop()print(loop.run_until_complete(run(loop)))

5、使用查询节点,尽量使用边的关系,避免使用标签前缀匹配

例如下面语句的执行时间为0.25s

g.V().filter{it.get().label().startsWith('a')}.has('class','59')
.has('name', 'name_5').valueMap('id', 'class', 'name').limit(10)

优化后的如下语句执行时间为0.04s

g.V().hasLabel('query').has('class','59').outE().inV()
.has('name', 'name_5').valueMap('id', 'class', 'name').limit(10)

6、使用边的关系和结果聚集

对于查询class=59,找出所有name的标签的index

方法一:

第一步:找出class对应的所有name,时间0.03s

g.V().hasLabel('query').has('class', '59').outE().inV()
.outE.valueMap('class', 'name').dedup('class', 'name')

第二步:找出每个name的index,每条语句执行时间为0.62s

g.V().filter{it.get().label().startsWith('b')}.has('class','59')
.has('name', 'name_5').valueMap('index').dedup('index')

或者执行下面语句,每条语句执行时间为0.04s

g.V().hasLabel('query').has('class', '59')
.outE().inV().has('name', 'name_5').outE().inV()
.valueMap('index').dedup('index')

使用并发访问最短可到0.04秒,但是又100个名称,需要执行101次请求

方法二:使用聚集的方法,如下,时间0.08s

g.V().hasLabel('query').has('class', '59').outE()
.inV().as('class', 'name', 'indexes')
.project('class', 'name', 'indexes').by('class').by('name')
.by(__.outE().inV().valueMap('index').fold())

方法三:使用group语句,时间为0.27s,当组数过多时性能有所降低

g.V().hasLabel('query').has('class', '59').outE().inV().outE().inV()
.group().by('name').by(valueMap('index').fold()).unfold()

参考资料:

Python:协程中 Task 和 Future 的理解及使用 - 简书

Gremlin中文文档

Gremlin -- 常用查询用法 - 云+社区 - 腾讯云

深入学习Gremlin(16):结果聚集与展开 - 程序员大本营


http://chatgpt.dhexx.cn/article/xtaPvbSy.shtml

相关文章

Gremlin学习笔记

前言 本文基于HugeGraph提供的HugeGraph-Studio编写示例代码,下图是示例关系图,示例数据在文末 基本概念 Gremlin是Apache TinkerPop框架下规范的图语言,相当于SQL之于关系型数据库 节点Vertex:一般指实体,如&#xf…

gremlin图查询插件

gremlin是一个通用的图查询插件,尽管在neo4j上可以使用Cypher语言进行查询,但我仍想调研一下通过gremlin查询neo4j。 1. 安装 插件下载地址:https://archive.apache.org/dist/tinkerpop/,这里下载了3.4.4版本的console和server压…

gremlin语法详解

初步认识 点:蓝色的圈代表顶点(查询语句中的V()),圈中的person代表顶点的名称,name和age为顶点的属性。 边:黑色的线代表边(查询语句中的E()),线上的knows代表边的名称,weight为边…

gremlin语句详解

到了新公司用到了tinkerPop的gremlin语句,由于是全英文的文档。为了杜绝我鱼记忆,决定整理一下以后查看方便。嗯嗯~ o(* ̄▽ ̄*)o 附图:语句来源于图片 初步认识: 点:蓝色的圈代表顶点&#xff…

图数据库入门教程-深入学习Gremlin(1):图基本概念与操作

前言:Gremlin语言是图数据库最主流的查询语言,是Apache TinkerPop框架下规范的图语言,相当于SQL之于关系型数据库。为了图数据库使用者更好的掌握Gremlin这门图语言,我们对Gremlin Steps进行了分类与总结,接下来将会出…

Gremlin:图遍历语言

Gremlin简介 Gremlin是Apache TinkerPop 框架下的图遍历语言。Gremlin是一种函数式数据流语言,可以使得用户使用简洁的方式表述复杂的属性图(property graph)的遍历或查询。每个Gremlin遍历由一系列步骤(可能存在嵌套)…

TWR双边测距

本篇承接UWB那篇,专门介绍下双边测距的原理。 1.单侧双边测距 如上图所示,设备A发起交换,设备B响应完成交换,每个设备精确地记录发送和接收时间戳信息。设备B在收到设备A的信号后,延迟固定的时间回发信号&#xff0…

Java 7 - TWR 和 多异常捕获 示例

为什么80%的码农都做不了架构师?>>> package interview.blob_clob;import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepared…

TWR_MPC8309调试日志

版权声明:本文为博主原创文章,未经博主允许不得转载。 TWR_MPC8309调试日志 --------By Moresung Chan , At 12:00 ,Sep 16,2012 一、软硬件: PC机操作系统:Microsoft Windows Server 2003 R2 开发板:TWR_MPC8309、…

DWM1000 测距原理简单分析 之 SS-TWR代码分析2 -- [蓝点无限]

蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 首先将SS 原理介绍中的图片拿过来,将图片印在脑海里。 对于DeviceA 和 DeviceB来说,初始化代码都一样,而后面部分…

Java 处理资源的try语句 (try-with-resources, TWR)

JAVA中try块的标准形式很通用,但有些常见的情况需要开发者小心编写catch和finally块。这些情况是清理或关闭不再需要使用的资源。 正常情况下,我们用try-catch-finally语句来实现打开文件资源,最后再关闭清理文件资源。例如下面的代码&#…

DWM1000 测距原理简单分析 之 SS-TWR

蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: DWM1000 超宽带测距,使用的TOF(time of fly) 的方式,也就是计算无线电磁波传输时间,通过传输的时间换算成距离。 电磁波传输速率和光速一样,速度是299792.458km/s,可参见百度百…

完成“LPS node 与Crazyflie在TWR协议下的成功双向测距”实现心路历程总结

完成“LPS node 与Crazyflie在TWR协议下的成功双向测距”实现心路历程总结 1.初识TWR协议2. TWR进阶1.03.TWR协议进阶2.04.TWR协议进阶3.05.TWR协议进阶4.06.总结 说来惭愧,这一点点东西做了快3个月[手动狗头.jpg] 但是这个协议的深入学习让我真正认识到研究生该怎样…

惠普台式机EliteDesk TWR安装双系统

关于HP EliteDesk 800 G4 TWR安装双系统 磁盘分区BIos界面操作Linux系统安装 由于需要在Linux系统下跑ros,但电脑有安装win10系统,为了不破坏Win10系统内的资料,所以就选择安装双系统,根据我之前的安装经验,装个双系统…

24C02 Twr

连续写24C02,只有第一次能够成功,后面写都失败了。这次调整写的时间间隔。调成了5ms,才成功。 查看datasheet,发现有一个tWR参数。表示写的最小时间间隔。这个时间应该是内部写入所需要的时间,如果连续写的时间过短,就会失败。 但…

DWM1000 测距原理简单分析 之 SS-TWR代码分析1 -- [蓝点无限]

蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 这一篇内容主要是通过官方源码理解SS-TWR 细节 代码下载链接:https://download.csdn.net/download/duanfei255/10787882 所有代码使用方法:复制example 中的main.c到Keil MDK工…

UWB定位算法比较TDOA和TWR究竟哪个好

使用UWB技术进行定位时,有两种基本定位算法:基于差分飞行时间(TDOA)和双向测距(TWR)的UWB定位算法,这两种算法各有优劣,下面将进行比较。 超宽带是一种可用于室内定位的短距离无线电…

HP EliteDesk 880 G2 TWR无法从U盘启用

一、客户需求 客户一台HP EliteDesk 880 G2 TWR台式机,想更换一块固态盘,于是即到哥带了一块固态盘上门给客户更换固态盘,重新安装系统。 更换完固态盘后,准备重新给客户安装系统。 客户的台式机型号是:HP EliteDesk …

java TWR是怎么优雅我们的代码的?

我们在编写IO代码的时候,有的时候真的是对对java IO那种模板化的代码感到厌倦,而且写出来的代码,很臃肿丑陋。像下面这样的代码: public void readFile(String filePath) {FileInputStream fis null;InputStreamReader inReader …

基于UWB的室内SDS_TWR测距算法优化和定位算法融合的研究

1、内容简介 略257 2、内容说明 1、RSSI定位方法 基于接收信号强度RSS(Receive Signal Strength)[57]方法通过三个及以上己知位置的锚节点来测量移动节点发射的信号场强强度,从而通过己有的传播损耗模型来估算移动节点距锚节点的距离,从而实现位置测量…