热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

KINGBASEQueryMapping查询映射功能

有过SQL优化经历的人都知道,对于有些SQL性能问题,可能需要涉及到SQL层面的修改,这不仅麻烦,而且在已上线的系统还存在很大的风险。KINGBASEV8R6提供了query

KINGBASE Query Mapping 查询映射功能

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

以下以举例介绍query mapping 的功能及使用。

一、设置功能开关参数

query mapping 功能开启与否,是通过参数 enable_query_rule 控制的。设置 enable_query_rule = on ,开启query mapping功能。

二、使用例子

1、准备数据

create table t1(id integer,name varchar(9));
insert into t1 select generate_series(1,1000000),"a"||generate_series(1000001,2000000);
create index ind_t1_name on t1(name);
create view v_t1 as select id,upper(name) name from t1;

例子建了个视图,视图对于索引列做了upper操作。upper 操作使得原有的索引无法使用。

2、Mapping前SQL 执行计划分析

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

test=# explain select id from v_t1 where name="A1234567";
                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 Seq Scan on t1  (cost=0.00..22906.00 rows=5000 width=4)
   Filter: (((upper((name)::text))::character varying(8000 char))::text = "A1234567"::text)

如果需要使用索引,只能修改SQL,直接查询表。可以看下执行计划:索引访问

test=# explain select id from t1 where name=lower("A1234567");
                              QUERY PLAN                              
----------------------------------------------------------------------
 Index Scan using ind_t1_name on t1  (cost=0.42..8.44 rows=1 width=4)
   Index Cond: ((name)::text = "a1234567"::text)

3、创建Query Mapping

像以上例子,可能修改SQL是不现实的,或是很麻烦的。有没有能不修改SQL,并且能快速解决问题的方法?KINGBASE Query Mapping 就是为实现该功能而量身定做的优化技术。

#创建SQL映射关系
select create_query_rule("qm1","select id from v_t1 where name=$1;","select id from t1 where name=lower($1);", true, "text");
select create_query_rule("qm2","select id from v_t1 where name=$1;","select id from t1 where name=lower($1);", true, "semantics");
#删除映射关系
select drop_query_rule("qm1"); 

在创建mapping时,有两种模式:

  • text在语法词法解析之前做的转化,字符串匹配,执行快。
  • semantics是转化为查询树之后再做转化,会进行语法检查,区分不同schema。对于过程或者匿名块内部的SQL,需要使用这种模式。优化器首先对匿名块作词法语法解析,然后执行的时候发现是查询的查询树,会先进行替换,生成执行计划。

可以查看sys_query_mapping,确认系统创建了哪些query mapping。

4、Mapping后执行计划

查询视图 v_t1 也可以使用到索引。

test=# explain (usingquerymapping, analyze) select id from v_t1 where name="A1234567";
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Index Scan using ind_t1_name on t1  (cost=0.42..8.44 rows=1 width=4) (actual time=0.018..0.019 rows=1 loops=1)
   Index Cond: ((name)::text = "a1234567"::text)
 Planning Time: 0.067 ms
 Execution Time: 0.035 ms
(4 rows)

注意红色部分不能少。

再看下不使用 (usingquerymapping, analyze) 情况下的执行计划:显示的是映射前的执行计划。

test=# explain  select id from v_t1 where name="A1234567";
                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 Seq Scan on t1  (cost=0.00..22906.00 rows=5000 width=4)
   Filter: (((upper((name)::text))::character varying(8000 char))::text = "A1234567"::text)
(2 rows)

 

4、如何确认Query Mapping是否升效?

如何确认SQL :select id from v_t1 where name=$1 是否会进行转换了?可以通过查询 sys_stat_statements 确认实际执行的SQL。

test=# select id from v_t1 where name="A1234567";     
   id   
--------
 234567
(1 row)

test=# select id from v_t1 where name="A1234567";
   id   
--------
 234567
(1 row)

test=# select id from v_t1 where name="A1234567";
   id   
--------
 234567
(1 row)

test=# select query,calls from sys_stat_statements where query like "%lower%";
                 query                  | calls 
----------------------------------------+-------
 select id from t1 where name=lower($1) |     3
(1 row)

可以看出SQL映射是生效的。

 三、Query Mapping对于性能影响

Query Mapping 在生成执行计划时,必须先读取sys_query_mapping,不可避免对于性能有一定影响。以下的例子可以看到,query mapping 还是会有20%左右的性能影响。

test=# declare
test-#   v_temp integer;
test-#   v_val text;
test-# begin
test-#   for i in 1000001..2010000 loop
test-#     execute "select id from t1 where name=$1" into v_temp using "a"||i;
test-#   end loop;
test-# end;
test-# /
Time: 102585.759 ms (01:42.586)

test=# declare
test-#   v_temp integer;
test-#   v_val text;
test-# begin
test-#   for i in 1000001..2010000 loop
test-#     execute "select id from v_t1 where name=$1" into v_temp using "A"||i;
test-#   end loop;
test-# end;
test-# /
Time: 128438.435 ms (02:08.438)
四、使用注意

query mapping 要求大写严格一致。

--表名 大小写不一致,无法使用query mapping
test=# explain (usingquerymapping, analyze) select id from V_T1 where name="A1234567";
                                              QUERY PLAN                                              
------------------------------------------------------------------------------------------------------
 Seq Scan on t1  (cost=0.00..22906.00 rows=5000 width=4) (actual time=99.525..407.516 rows=1 loops=1)
   Filter: (((upper((name)::text))::character varying(8000 char))::text = "A1234567"::text)
   Rows Removed by Filter: 999999
 Planning Time: 0.448 ms
 Execution Time: 407.542 ms
(5 rows)

--空格后面不一致,不影响 query mapping使用 test
=# explain (usingquerymapping, analyze) select id from v_t1 where name="A1234567"; QUERY PLAN ---------------------------------------------------------------------------------------------------------------- Index Scan using ind_t1_name on t1 (cost=0.42..8.44 rows=1 width=4) (actual time=0.022..0.022 rows=1 loops=1) Index Cond: ((name)::text = "a1234567"::text) Planning Time: 0.062 ms Execution Time: 0.036 ms (4 rows)
--FROM 大小写不一致,无法使用query mapping test
=# explain (usingquerymapping, analyze) select id From v_t1 where name="A1234567"; QUERY PLAN ------------------------------------------------------------------------------------------------------ Seq Scan on t1 (cost=0.00..22906.00 rows=5000 width=4) (actual time=98.008..417.077 rows=1 loops=1) Filter: (((upper((name)::text))::character varying(8000 char))::text = "A1234567"::text) Rows Removed by Filter: 999999 Planning Time: 0.159 ms Execution Time: 417.097 ms (5 rows)

推荐阅读
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文提供了关于数据库设计的建议和注意事项,包括字段类型选择、命名规则、日期的加入、索引的使用、主键的选择、NULL处理、网络带宽消耗的减少、事务粒度的控制等方面的建议。同时还介绍了使用Window Functions进行数据处理的方法。通过遵循这些建议,可以提高数据库的性能和可维护性。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 开发笔记:select from具体执行相关知识介绍及案例分析
    本文由编程笔记小编整理,主要介绍了select from具体执行相关的知识,包括数据插入、查询最小rowID、查询每个重复名字的最小rowID、删除重复数据等操作,并提供了案例分析。希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • MySQL插入数据的四种方式及安全性分析
    本文介绍了MySQL插入数据的四种方式:插入完整的行、插入行的一部分、插入多行和插入查询结果,并对其安全性进行了分析。在插入行时,应注意字段的定义和赋值,以提高安全性。同时指出了使用insert语句的不安全性,应尽量避免使用。建议在表中定义相关字段,并根据定义的字段赋予相应的值,以增加插入操作的安全性。 ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
author-avatar
qk墨砚轩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有