摘要:在DBMS中,参数化查询被视为一种有效预防SQL注入攻击的手段。

本文分享自华为云社区《使用参数化查询提高Cypher查询的性能:以华为云图引擎GES为例》,作者: 蜉蝣与海。

在DBMS中,参数化查询被视为一种有效预防SQL注入攻击的手段。华为云图引擎GES提供对gremlin和cypher查询语言的参数化查询支持,使用参数化查询不仅可以防止前端用户随意输入恶意指令影响语句执行,还可以有效利用查询编译缓存,提高查询性能。

参数化查询(Parameterized Query),Wiki中的解释是:客户端在向数据服务端发送和请求查询语句时,在需要填入数值或者用户输入的字符串数据的地方,使用一个变量名来替代,并在请求体中解释每个变量名所指代的内容。在这种情况下,由于变量名指代的内容不会参与SQL语言的查询编译,即使用户输入数据中包含一些破坏性的指令,也不会被数据库运行。

举例说明,使用Cypher-JDBC-Driver访问华为云图引擎,可以进行对应的参数设置:

public static void main(String[] args) throws ClassNotFoundException {
Class.forName("com.huawei.ges.jdbc.Driver");
String url = "jdbc:ges:http://{{graph_ip}}:{{graph_port}}/ges/v1.0/{{project_id}}/graphs/{{graph_name}}/action?action_id=execute-cypher-query";
url = url.replace("{{graph_ip}}", ip).replace("{{graph_port}}",port + "").replace("{{project_id}}", projectId).replace("{{graph_name}}", graphName);
Properties prop = new Properties();
prop.setProperty("X-Auth-Token", token);
prop.setProperty("limit","40");
try(Connection conn = DriverManager.getConnection(url,prop)){
String query = "match (n:movie) where n.genres=? return n.title";
try(PreparedStatement stmt = conn.prepareStatement(query)){
stmt.setString(1, "Comedy");
try(ResultSet rs = stmt.executeQuery()){
while(rs.next()) {
System.out.println(rs.getString("n.title"));
}
}
}
} catch (SQLException e) {
// do something for e.
}
}

其中查询语句中的问号即是JDBC风格的参数化查询变量,后面代码中通过setString方法为其设置一个值“Comedy”。

同时,参数化查询可以使得不同的用户输入使用同一条参数化查询语句执行,可以高效利用数据库查询缓存,节省了查询编译时间,从而提升了查询性能。例如,下图是使用Freebase数据集构造的若干2跳3跳查询,在华为云图引擎GES中运行, 参数化查询前后QPS的变化。可以看到使用参数化查询,qps获得了2-8倍的提升。

为什么参数化查询可以提高查询qps?首先要简单介绍下数据服务在收到查询语句后都做了什么。在数据管理领域,数据服务接收到查询语句,往往会进行下列步骤: 词法&语法解析,查询计划生成,查询计划执行,如图。

这里简单说一下查询计划生成。现在大多数查询计划的生成策略,要么是基于代价的查询计划生成,要么是基于规则的查询计划生成,或者二者组合使用。而不管是哪种查询计划生成,都是偏向计算密集型的任务,比较耗费服务器的计算资源,同一时间系统只能并行处理有限数目的查询计划生成任务。在计划生成器内部,大多数数据库都会内置查询缓存,即在一定的时间范围内,同一条查询语句输入计划器,计划器优先从查询缓存中检查有无可用计划,如果缓存中生成的计划时间太长或者无可用计划,才会真正执行计划生成的过程。

因此使用参数化查询时,由于使用不同参数的查询语句语句体相同,在查询编译阶段更容易被认为是同一条查询语句, 从而实现“多次查询,一次编译”的效果,也就提高了查询编译效率。

附录:

Freebase数据集属性图格式规模:

查询语句:

2hop_Q1: match (n1)-[r]->(m1)-->(p1) where id(n1)=$vertex return id(p1) limit 100
2hop_Q2: match (n1)-[r]->(m1)-->(p1) where id(n1)=$vertex return p1.name limit 100
2hop_Q3: match(n)-[r]->(m)-->(p) where id(n)=$vertex and m.games > 10 and p.name contains 'NBA' return p
3hop_Q1: match (n1)-[r1]-(m1)-[r2]-(p1)--(p2) where id(n1)=$vertex and m1.game > 0 return id(p2) limit 100
3hop_Q2: match (n1)-[r1]-(m1) match (m1)-[r2]-(p1) match (p1)--(p2) where id(n1)=$vertex and m1.games > 0 return id(p2)

相关参考:

[1]参数化查询_百度百科:https://baike.baidu.com/item/%E5%8F%82%E6%95%B0%E5%8C%96%E6%9F%A5%E8%AF%A2/4841802?fr=aladdin

[2]GES cypher API: https://support.huaweicloud.com/api-ges/ges_03_0212.html

[3]Github - opencypher:https://github.com/opencypher/openCypher

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

如何使用参数化查询提高Cypher查询的性能的更多相关文章

  1. 并行查询提高sql查询速度

    新项目在使用Oracle开发中遇到测试库千万级数据导致数据慢,除去加索引和存储过程可以明显提速外,使用并行也可以提速 select /*+parallel(a,8)*/ a.* from a 加上/* ...

  2. 提高SQL查询效率(SQL优化)

    要提高SQL查询效率where语句条件的先后次序应如何写 http://blog.csdn.net/sforiz/article/details/5345359   我们要做到不但会写SQL,还要做到 ...

  3. 提高SQL查询效率的常用方法

    提高SQL查询效率的常用方法 (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driv ...

  4. 防SQL注入:生成参数化的通用分页查询语句

    原文:防SQL注入:生成参数化的通用分页查询语句 前些时间看了玉开兄的“如此高效通用的分页存储过程是带有sql注入漏洞的”这篇文章,才突然想起某个项目也是使用了累似的通用分页存储过程.使用这种通用的存 ...

  5. 提高MySQL查询速度

    参考百度知道 关于mysql处理百万级以上的数据时如何提高其查询速度的方法 最近一段时间由于工作需要,开始关注针对Mysql数据库的select查询语句的相关优化方法. 由于在参与的实际项目中发现当m ...

  6. Neo4j使用Cypher查询图形数据

    Neo4j使用Cypher查询图形数据,Cypher是描述性的图形查询语言,语法简单,功能强大,由于Neo4j在图形数据库家族中处于绝对领先的地位,拥有众多的用户基数,使得Cypher成为图形查询语言 ...

  7. Neo4j 第三篇:Cypher查询入门

    本文转载自:https://www.cnblogs.com/ljhdo/p/5516793.html Neo4j使用Cypher查询图形数据,Cypher是描述性的图形查询语言,语法简单,功能强大,由 ...

  8. 提高SQL查询效率的30种方法

    转载:提高SQL查询效率的30种方法 内容摘录如下: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中 ...

  9. 使用Oracle的instr函数与索引配合提高模糊查询的效率

    使用Oracle的instr函数与索引配合提高模糊查询的效率 一般来说,在Oracle数据库中,我们对tb表的name字段进行模糊查询会采用下面两种方式:1.select * from tb wher ...

  10. Redis进阶实践之十八 使用管道模式提高Redis查询的速度

    原文:Redis进阶实践之十八 使用管道模式提高Redis查询的速度 一.引言             学习redis 也有一段时间了,该接触的也差不多了.后来有一天,以为同事问我,如何向redis中 ...

随机推荐

  1. xtrabackup 2.4 的介绍与使用

    抄袭转载的太多,请认准原文链接:xtrabackup的介绍与使用 前言 在网上找到教程都是复制粘贴抄袭的,而且还是陈旧资料,不得不说,当前中文互联网环境真是每况愈下. 如果你在网上找 xtraback ...

  2. Java Exception最佳实践(转)

    https://www.dubby.cn/detail.html?id=9033 1.异常介绍 2.Java中的异常介绍 3.自定义异常 4.几个建议 1)不要生吞异常 2)申明具体的异常 3)尽可能 ...

  3. PostgreSQL 提升子连接与 ORACLE 子查询非嵌套

    查询优化器对子查询一般采用嵌套执行的方式,即父查询中的每一行,都要执行一次子查询,这样子查询会执行很多次,效率非常低. 例如 exists.not exists 逐行取出经行匹配处理,项目中使用子查询 ...

  4. gametime

    这道题是动态调试的考点,看了wp才有思路 像这样的游戏题一定要搞清楚他的具体游戏流程才能更好的做出来,然后根据他的思路去改掉相关的判断就可以了 攻防世界逆向高手题之gametime_攻防世界 game ...

  5. Python数字加密方法:建立从0到9的数字序列,将输入的数字数据,每个数字在数字序列中循环右移2位,输出该数据对应的汉字大写形式。

    数字加密方法:建立从0到9的数字序列,将输入的数字数据,每个数字在数字序列中循环右移2位,输出该数据对应的汉字大写形式. 样例1:输入123,输出三四五 样例2:输入985,输出一零七 def Slo ...

  6. HBuilderX代码提示失效解决方案

    用了一段时间后,HBuilderX的代码提示功能突然不生效了,重新下载也没有用,解决方案是重置默认配置 提示:重置配置会清除编辑器内的项目,记得先保存 解决方案 1.找到HBuilderX根目录下的r ...

  7. 3. Shell 条件判断

    重点: 条件测试. read. Shell 环境配置. case. for. find. xargs. gzip,bzip2,xz. tar. sed. 1)Shell 的配置文件 Bash Shel ...

  8. MongoDB中的分布式集群架构

    MongoDB 中的分布式集群架构 前言 Replica Set 副本集模式 副本集写和读的特性 Sharding 分片模式 分片的优势 MongoDB 分片的组件 分片键 chunk 是什么 分片的 ...

  9. 2023-12-23:用go语言,一支n个士兵的军队正在趁夜色逃亡,途中遇到一条湍急的大河 敌军在T的时长后到达河面,没到过对岸的士兵都会被消灭 现在军队只找到了1只小船,这船最多能同时坐上2个士兵。

    2023-12-23:用go语言,一支n个士兵的军队正在趁夜色逃亡,途中遇到一条湍急的大河 敌军在T的时长后到达河面,没到过对岸的士兵都会被消灭 现在军队只找到了1只小船,这船最多能同时坐上2个士兵. ...

  10. .NET开发中合理使用对象映射库,简化和提高工作效率

    前言 在日常开发中,我们常常需要将一个对象映射到另一个对象,这个过程中可能需要编写大量的重复性代码,如果每次都手动编写,不仅会影响开发效率,而且当项目越来越复杂,庞大的时候还容易出现错误.为了解决这个 ...