什么是QueryMapping

KingbaseES Query Mapping 是一种查询映射功能。有过SQL优化经历的人都知道,对于有些SQL性能问题,可能需要涉及到SQL层面的修改,这不仅麻烦,而且在已上线的系统还存在很大的风险。KingbaseES V8R6 提供了query mapping功能,用户可以通过SQL映射,可以避免直接修改SQL的过程。

QueryMapping的作用

一个无法使用索引的查询语句,通过QueryMapping,可以解决性能问题。

假设应用有这么一条SQL : select id from v_t1 where upper(name)=$1; 可以看下执行计划:由于做了upper转换,无法使用索引。

kingbase=# explain analyze select id from t1 where upper(name)='A1234567';
QUERY PLAN
------------------------------------------------------------------------------------------------------
Seq Scan on t1 (cost=0.00..20435.00 rows=5000 width=4) (actual time=44.860..190.009 rows=1 loops=1)
Filter: (upper(name) = 'A1234567'::text)
Rows Removed by Filter: 999999
Planning Time: 0.113 ms
Execution Time: 190.025 ms
(5 行记录)

KingbaseES Query Mapping 实现不修改SQL,并且能快速解决问题。

set enable_query_rule = on
--创建SQL映射关系
select create_query_rule('qm1','select id from t1 where upper(name)=$1;','select id from t1 where name=lower($1);', true, 'text'); explain (usingquerymapping,analyze) select id from t1 where upper(name)='A1234567';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Index Scan using ind_t1_name on t1 (cost=0.42..8.44 rows=1 width=4) (actual time=0.024..0.025 rows=1 loops=1)
Index Cond: (name = 'a1234567'::text)
Planning Time: 0.089 ms
Execution Time: 0.040 ms
(4 行记录)

延伸思考

KingbaseES Query Mapping用一个性能良好的SQL语句,替换原SQL语句,实现性能的提升。如果SQL语句的执行性能良好,但解析性能较慢,是否可以解决SQL语句仅能在事务中实现软解析。

实验场景

一个复杂查询

一个语句复杂的视图,虽然执行性能优良,但解析需要较长的时间,造成查询语句的整体运行时间较长。


kingbase=# explain analyze select id from sch01.v_tun1k where id = 8888;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
Append (cost=0.28..8293.50 rows=1000 width=4) (actual time=0.088..4.602 rows=1 loops=1)
...
Planning Time: 376.659 ms
Execution Time: 6.621 ms

每次查询返回结果的时间,如下。


kingbase=# select id from sch01.v_tun1k where id = 888; \watch
id
-----
888
(1 行记录) 时间:374.361 ms
2022年09月25日 星期日 15时23分37秒 (每 2s) id
-----
888
(1 行记录) 时间:377.814 ms
2022年09月25日 星期日 15时23分39秒 (每 2s) id
-----
888
(1 行记录) 时间:381.633 ms
2022年09月25日 星期日 15时23分41秒 (每 2s) id
-----
888
(1 行记录) 时间:382.636 ms
2022年09月25日 星期日 15时23分44秒 (每 2s) id
-----
888
(1 行记录) 时间:378.316 ms

函数实现软解析

使用函数可以在同一会话中,执行6次后,实现软解析。


create or replace function f_tun1k(int)
returns table(id int)
language plsql
as
$$
begin
return query select id from sch01.v_tun1k where id = $1;
end;
$$
;

kingbase=# select *,round(date_part('sec',clock_timestamp()-now())*1000,3)||'ms' ms from f_tun1k(8888) ;\watch
id | ms
------+-----------
8888 | 456.109ms
(1 行记录) 2022年09月25日 星期日 15时12分00秒 (每 2s) id | ms
------+-----------
8888 | 382.978ms
(1 行记录) 2022年09月25日 星期日 15时12分02秒 (每 2s) id | ms
------+-----------
8888 | 391.402ms
(1 行记录) 2022年09月25日 星期日 15时12分05秒 (每 2s) id | ms
------+-----------
8888 | 380.328ms
(1 行记录) 2022年09月25日 星期日 15时12分07秒 (每 2s) id | ms
------+-----------
8888 | 385.995ms
(1 行记录) 2022年09月25日 星期日 15时12分09秒 (每 2s) id | ms
------+-----------
8888 | 382.862ms
(1 行记录) 2022年09月25日 星期日 15时12分12秒 (每 2s) id | ms
------+---------
8888 | 9.208ms
(1 行记录) 2022年09月25日 星期日 15时12分14秒 (每 2s) id | ms
------+---------
8888 | 7.971ms
(1 行记录) 2022年09月25日 星期日 15时12分16秒 (每 2s) id | ms
------+---------
8888 | 8.243ms
(1 行记录)

将函数与QueryMapping结合

创建SQL映射关系


kingbase=# select create_query_rule('qm10', 'select id from sch01.v_tun1k where id = $1;', 'select id from f_tun1k($1) ;', true, 'text');
create_query_rule
------------------- (1 行记录)

函数与QueryMapping结合的效果,在同一会话中,原SQL实现了软解析。


kingbase=# select id from sch01.v_tun1k where id = 888; \watch
id
-----
888
(1 行记录) 时间:10.250 ms
2022年09月25日 星期日 15时21分34秒 (每 2s) id
-----
888
(1 行记录) 时间:7.958 ms
2022年09月25日 星期日 15时21分36秒 (每 2s) id
-----
888
(1 行记录) 时间:9.958 ms
2022年09月25日 星期日 15时21分38秒 (每 2s) id
-----
888
(1 行记录) 时间:10.581 ms
2022年09月25日 星期日 15时21分40秒 (每 2s) id
-----
888
(1 行记录) 时间:11.401 ms

在语句块中实现软解析

创建SQL映射关系,在语句块中实现QueryMapping,需要semantics键值。

kingbase=# select create_query_rule('qm11', 'select id from sch01.v_tun1k where id = $1;', 'select id from f_tun1k($1) ;', true, 'semantics');
create_query_rule
------------------- (1 行记录)

在一个会话中,语句块使用组合的软解析效果。


kingbase=# do
kingbase-# $$
kingbase$# declare
kingbase$# v_id int ;
kingbase$# v_ref int;
kingbase$# begin
kingbase$# v_id := (random() * 1000000)::int;
kingbase$# select id into v_ref from sch01.v_tun1k where id = v_id;
kingbase$# raise notice ' ID = % , % ',v_ref , round(date_part('sec', clock_timestamp() - now()) * 1000,3) || 'ms';
kingbase$# end;
kingbase$# $$ \watch
注意: ID = 387169 , 8.635ms
2022年09月25日 星期日 15时33分01秒 (每 2s) ANONYMOUS BLOCK 注意: ID = 35458 , 10.489ms
2022年09月25日 星期日 15时33分03秒 (每 2s) ANONYMOUS BLOCK 注意: ID = 39627 , 9.775ms
2022年09月25日 星期日 15时33分05秒 (每 2s) ANONYMOUS BLOCK 注意: ID = 730817 , 10.634ms
2022年09月25日 星期日 15时33分07秒 (每 2s) ANONYMOUS BLOCK 注意: ID = 582763 , 9.363ms
2022年09月25日 星期日 15时33分09秒 (每 2s) ANONYMOUS BLOCK 注意: ID = 148173 , 9.186ms
2022年09月25日 星期日 15时33分11秒 (每 2s) ANONYMOUS BLOCK 注意: ID = 800521 , 9.766ms
2022年09月25日 星期日 15时33分13秒 (每 2s) ANONYMOUS BLOCK

总结

目前,QueryMapping功能需要手动创建查询脚本的对照关系,不便于大规模的应用,对于频繁且无法优化的查询,也可以提升执行性能。

KingabseES例程之巧用QueryMapping解决查询硬解析问题的更多相关文章

  1. memcache锁,解决查询过多email查询为空的问题

    /* 设置memcache锁,解决查询过多email查询为空的问题 Begin */ $mmc = new Memcache; $mmc->connect('127.0.0.1', 11211) ...

  2. dataGridView1.DataSource,解决查询结果不从第一行显示,而是不断往表下面扩展问题

    private void 洱海各月出流流量frm_Load(object sender, EventArgs e) { //在查询按钮中用下面这段代码会出现打开数据库出错的现象 MyTable1.Ro ...

  3. 解决域名DNS解析的故障

    在实际应用过程中可能会遇到DNS解析错误的问题,就是说当我们访问一个域名时无法完成将其解析到IP地址的工作,而直接输入网站IP却可以正常访问,这就是因为DNS解析出现故障造成的.这个现象发生的机率比较 ...

  4. 使用dig查询dns解析

    原文地址:使用dig查询dns解析 作者:chenwenming 一般来说linux下查询域名解析有两种选择,nslookup或者dig,而在使用上我觉得dig更加方便顺手. 如果是在debian下的 ...

  5. Node基础:url查询参数解析之querystring

    模块概述 在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单. 模块总共有四个方法,绝大部分时,我们只会用到 .parse(). .stringify() ...

  6. 将查询字符串解析转换为泛型List的名值集合.

    ///<summary> ///将查询字符串解析转换为泛型List的名值集合. ///</summary> ///<param name="queryStrin ...

  7. 解决JSP 不解析EL表达式

    解决JSP 不解析EL表达式,jsp在使用EL表达式的时候发现它不被解析,而是直接以字符串的形式显示了出来,经过查阅资料和实践,终于得知了原因并找到了解决方案 原因是:在默认情况下,Servlet 2 ...

  8. IOS CoreData 多表查询demo解析

    在IOS CoreData中,多表查询上相对来说,没有SQL直观,但CoreData的功能还是可以完成相关操作的. 下面使用CoreData进行关系数据库的表与表之间的关系演示.生成CoreData和 ...

  9. 关于ORACLE的硬解析和软解析与MySQL的查询缓存query_cache探讨

    今天在项目中探讨到Oracle对于SQL语句的解析方法以及MySQL相应的处理方法: --------------------------------------------------------- ...

  10. Oracle 硬解析查询

    -- 硬解析的 parse count (hard) select * from v$sysstat where name like '%parse%'; select a.value,b.name ...

随机推荐

  1. image could not be accessed on a registry to record its digest

    问题说明: 在管理节点执行docker stack xxx 方式运行服务,报如题错误. 问题原因: docker swarm运行需要一个镜像仓库才行,所有节点都去这个仓库统一镜像. 来看下官方的解释: ...

  2. nginx配置反向代理缓存

    说明 最近运维一个网站里面含有不经常变化的小图片,而每次请求都需要调用file接口获取不太合适.所以就想利用nginx的反向代理缓存来减轻服务接口的请求压力. 工作原理 Nginx反向代理缓存,当客户 ...

  3. oracle中使用自定义函数解析指定分隔符的字符串

    1.创建字符串表类型 create type tab_varchar is table of varchar2(2000); 2.创建管道函数 create or replace function g ...

  4. win32 - 计算位图所需的字节总数

    BITMAPINFOHEADER文档详细介绍了所需要的步骤, 对于未压缩的RGB格式,最小跨度始终是图像宽度(以字节为单位),四舍五入到最接近的DWORD.可以使用以下公式来计算步幅: stride ...

  5. 树莓派开发笔记(十六):树莓派4B+安装mariadb数据库(mysql开源分支)并测试基本操作

    前言   树莓派使用数据库时,优先选择sqlite数据库,但是sqlite是文件数据库同时仅针对于单用户的情况,考虑到多用户的情况,在树莓派上部署安装mariadb数据库服务(mysql的开源分支), ...

  6. vscode自定义运行和调试创建launch.json文件及项目独立配置文件

    1.创建lauch.json文件 2.然后在项目目录中会自动创建.vscode的目录 3.在.vscode目录下创建settings.json项目独立配置文件 4.在settings.json中写入 ...

  7. 【LeetCode回溯算法#11】解数独,这次是真的用回溯法处理二维数组

    解数独 力扣题目链接(opens new window) 编写一个程序,通过填充空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出 ...

  8. 【Azure Redis 缓存 Azure Cache For Redis】Redis支持的版本及不同版本迁移风险

    问题描述 1. Azure Redis缓存支持的版本包括4.0以及6.0(预览) 这种情形下,可以使用PaaS服务提供的 Azure Redis 缓存(4.0版本).Azure Redis对6.0的支 ...

  9. 【Azure 应用服务】如何定期自动重启 Azure App Service Plan(应用服务计划)

    问题描述 如何定期自动重启 Azure App Service Plan(应用服务计划)? 因一个App Service Plan 下包含多个应用服务,如果能统一通过应用服务计划来重启所有的应用,则有 ...

  10. clickhouse 安装启动报<Error> Application: DB::Exception: There is no profile 'default' in configuration file. 以及常见的错误的总结

    1.启动时报错<Error> Application: DB::Exception: There is no profile 'default' in configuration file ...