https://www.cnblogs.com/kingbase/p/14798059.html

Postgresql 常用的字符数据类型的有char、varchar和text,其中 char 固定长度类型, varchar 和 text 是可变长度类型。这三种类型在进行比较时,会进行隐含的类型转换。这种转换会导致索引可能无法使用,影响SQL的执行计划。以下以例子的形式展示Postgresql 不同字符数据类型间的转换规则。

一、创建测试数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
create table test_char(id char(9),desc_info text);
create table test_varchar(id varchar(9),desc_info text);
create table test_text(id text,desc_info text);
insert into test_char select generate_series(100001,200000),repeat('a',100);
insert into test_varchar select generate_series(100001,200000),repeat('a',100);
insert into test_text select generate_series(100001,200000),repeat('a',100);
create index ind_test_char on test_char(id);
create index ind_test_varchar on test_varchar(id);
create index ind_test_text on test_text(id);
analyze test_char;
analyze test_varchar;
analyze test_text;

二、创建SQL游标

1
2
3
4
5
6
7
8
prepare test_char_bind_varchar(varcharas select from test_char where id=$1;
prepare test_char_bind_text(text) as select from test_char where id=$1;
prepare test_varchar_bind_char(charas select from test_varchar where id=$1;
prepare test_text_bind_char(charas select from test_text where id=$1;
prepare test_varchar_bind_text(text) as select from test_varchar where id=$1;
prepare test_text_bind_varchar(varcharas select from test_text where id=$1;

三、Postgresql字符类型的隐含转换规则

1、对于 varchar 与 char 比较,默认是 varchar 转成 char。

例子2,由于等式左边发生了类型转换,无法使用索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
例子1:
testdb=# explain execute test_char_bind_varchar('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_char on test_char  (cost=0.42..8.44 rows=1 width=111)
   Index Cond: (id = '123456'::bpchar)
(2 rows)
例子2:等式左边发生类型转换,无法使用索引
testdb=# explain execute test_varchar_bind_char('123456');
                           QUERY PLAN                           
-----------------------------------------------------------------
 Seq Scan on test_varchar  (cost=0.00..2975.00 rows=1 width=108)
   Filter: ((id)::bpchar = '123456'::bpchar)
(2 rows)

2、对于 text 与 char 比较,默认是 char 转成 text 。

例子3,由于等式左边发生了类型转换,无法使用索引。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
例子3:等式左边发生类型转换,无法使用索引。
testdb=# explain execute test_char_bind_text('123456');
                           QUERY PLAN                          
----------------------------------------------------------------
 Seq Scan on test_char  (cost=0.00..3225.00 rows=500 width=111)
   Filter: ((id)::text = '123456'::text)
(2 rows)
例子4:
testdb=# explain execute test_text_bind_char('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_text on test_text  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: (id = '123456'::text)
(2 rows)

3、对于 varchar 与 text 比较,默认是 varchar 转成 text ,但二者的转换不影响索引的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
testdb=# explain execute test_varchar_bind_text('123456');
                                      QUERY PLAN                                      
---------------------------------------------------------------------------------------
 Index Scan using ind_test_varchar on test_varchar  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: ((id)::text = '123456'::text)
(2 rows)
testdb=# explain execute test_text_bind_varchar('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_text on test_text  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: (id = '123456'::text)
(2 rows)

PG 字符类型数据转换规则:varchar -> char -> text

四、KingbaseES 类型转换及优化

用过Oracle的人都知道,char与varchar 之间的比较不会因为类型不同而无法使用索引,Kingbase在特性上向Oracle靠拢,为用户从Oracle向KingbaseES迁移提供便利。KingbaseES 继承Postgresql 的特性,同时通过代码的优化,避免了char与varchar和text之间比较导致的转换而无法使用索引的情况。以下的例子在KingbaseES V8R6 版本进行过实际验证。

1、对于 varchar 与 char 比较,同样是 varchar 转成 char。

kingbase 针对这个问题,进行了特殊的优化处理,即使等式左边的varchar发生了类型转换,也不影响索引的使用,如:例子6。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
例子5:
testdb=# explain execute test_char_bind_varchar('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_char on test_char  (cost=0.42..8.44 rows=1 width=111)
   Index Cond: (id = '123456'::bpchar)
(2 rows)
例子6:不会因为等式左边发生类型转换而无法使用索引。
testdb=# explain execute test_varchar_bind_char('123456');
                                      QUERY PLAN                                      
---------------------------------------------------------------------------------------
 Index Scan using ind_test_varchar on test_varchar  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: ((id)::text = '123456'::text)
(2 rows)

2、对于 text 与 char 比较,kingbase 进行了特殊的优化处理,使得转换发生在等式的右边,不影响索引的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
例子7:
testdb=# explain execute test_char_bind_text('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_char on test_char  (cost=0.42..8.44 rows=1 width=111)
   Index Cond: (id = '123456'::bpchar)
(2 rows)
例子8:
testdb=# explain execute test_text_bind_char('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_text on test_text  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: (id = '123456'::text)
(2 rows)

3、对于 varchar 与 text 比较,默认是 varchar 转成 text 。与PG一样,二者的转换不影响索引的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
test=# explain execute test_varchar_bind_text('123456');
                                      QUERY PLAN                                      
---------------------------------------------------------------------------------------
 Index Scan using ind_test_varchar on test_varchar  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: ((id)::text = '123456'::text)
(2 rows)
test=# explain execute test_text_bind_varchar('123456');
                                   QUERY PLAN                                   
---------------------------------------------------------------------------------
 Index Scan using ind_test_text on test_text  (cost=0.29..8.31 rows=1 width=108)
   Index Cond: (id = '123456'::text)
(2 rows)

Tips:以上例子是基于Postgresql 12.3 和 KingbaseES V8R6版本测试的结果。

[转帖]KingbaseES不同字符类型比较转换规则的更多相关文章

  1. KingbaseES不同字符类型比较转换规则

    Postgresql 常用的字符数据类型的有char.varchar和text,其中 char 固定长度类型, varchar 和 text 是可变长度类型.这三种类型在进行比较时,会进行隐含的类型转 ...

  2. 字符类数据类型和oracle字符类型的区别

    为兼容Oracle的数据类型,KingbaseES扩展了Oracle的NUMBER.VARCHAR2.CHAR(n)和DATE类型.该措施使得移植Oracle的Create Table等DDL语句时, ...

  3. kingbase字符类数据类型和oracle字符类型的区别

    为兼容Oracle的数据类型,KingbaseES扩展了Oracle的NUMBER.VARCHAR2.CHAR(n)和DATE类型.该措施使得移植Oracle的Create Table等DDL语句时, ...

  4. 交叉报表列头排序时遇到的oracle问题—oracle ORA-12704:字符集不匹配、varchar2转化为nvarchar2字符缺失、case when else后的字符类型要一致

    在做交叉报表列头的排序时,遇到这三个问题,下面具体来说一下. 设计的数据库的表结构如图1所示: 图1 要处出来student_name_,s.grade_,s.subject_name_,这三个属性, ...

  5. 2016年11月3日JS脚本简介数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6.布尔型数据:bool 7.对象类型:object 8.二进制:binary 语言类型: 1.强类型语言:c++ c c# java 2.弱类型语

    数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6 ...

  6. ABAP 使用的字符类型

    1.ABAP基本数据类型 类型        描述                属性 C            字符类型           默认长度1,最大长度不限N            数字类 ...

  7. 【笨嘴拙舌WINDOWS】字符类型与字符串

    "我将用C语言作为工具,开始WINDOWS API的使用" windows NT 从底层开始支持unicode. 1.字符类型 WINDOWS的字符类型在WINNT.H和CTYPE ...

  8. js密码的校验(判断字符类型、统计字符类型个数)

    /** *判断字符类型 */ function CharMode(iN) { if (iN >= 48 && iN <= 57) //数字 return 1; if (iN ...

  9. 返璞归真vc++之字符类型

    在今天,大量使用java与.net的程序员已经很少去真实了解字符的底层表达,但是使用VC++编程,对字符的处理却非常慎重,刚学习vc++肯定会为其中的字符类型给晕头转向,今天本人学习第一节,从字符开始 ...

  10. Python 基础-python环境变量、模块初识及字符类型

    (1).模块内置模块.第三方模块.自定义模块初识模块:sys \ os一般标准库存放路径 C:\Users\Administrator\AppData\Local\Programs\Python\Py ...

随机推荐

  1. 如何解决windos系统关闭nginx进程之后仍然可以访问?

    1.停止Nginx服务的四种方法 从容停止服务 这种方法较stop相比就比较温和一些了,需要进程完成当前工作后再停止. nginx -s quit 立即停止服务 这种方法比较强硬,无论进程是否在工作, ...

  2. 文心一言 VS 讯飞星火 VS chatgpt (47)-- 算法导论6.1 5题

    五.一个已排好序的数组是一个最小堆吗? 文心一言: 一个已排好序的数组不一定是一个最小堆.最小堆是一种特殊的二叉树,它满足以下性质:对于任意节点 x,其父节点 y 的值都小于等于 x 的值.而一个已排 ...

  3. 最大伪森林——kruskal算法活用 (HDU - 3367)

    最大伪森林--kruskal算法活用 (HDU - 3367) kruskal这一用来求生成树的算法,经过修改拓展之后,可以求很多种形式的子图,本题(HDU3367)即为一个应用案例 单击进入原题 以 ...

  4. 【技术总结】从Hash索引到LSM树

    摘要:本文将从实现最简单的Key-Value数据库讲起,然后针对实现过程中遇到的一些瓶颈,采用上述的索引技术,对数据库进行优化,以此达到对数据库的索引技术有一个较为深刻的理解. 前言 数据库算是软件应 ...

  5. MES/MOM国内市场现状趋势与新生态模式参考

    本文分享自华为云社区<工业互联网系列(七)MES/MOM国内市场现状趋势与新生态模式参考>,作者:云起MAE . 国内工业互联网平台服务整体围绕数字化及数据价值挖掘的底层逻辑没有变,变的是 ...

  6. 火山引擎 DataTester 智能发布平台:智能化 A/B 实验,助力产品快速迭代

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在互联网竞争炙热的红海时代,精益开发高效迭代越来越成为成为产品竞争的利器.产品迭代过程中,如何保障高效的功能迭代安 ...

  7. Spring Boot JWT 用户认证

    JWT token验证后,通过 ThreadLocal 进行传值 https://jwt.io/#debugger 官网提供的 JAVA 工具还是挺多的,选了个 Star 比较多的 https://g ...

  8. 使用jasypt加密配置的时候,报错:DecryptionException: Unable to decrypt

    前几天分享了一篇<Spring Boot 2.x基础教程:加密配置中的敏感信息> ,然后看到群里有小伙伴反应跟着这篇文章出现了这个异常com.ulisesbocchio.jasyptspr ...

  9. 源码深度解析 Handler 机制及应用

    本文以源码分析+实际应用的形式,详细讲解了 Handler 机制的原理,以及在开发中的使用场景和要注意的地方. 一.基本原理回顾 在 Android 开发中,Handler及相关衍生类的应用经常用到, ...

  10. RabbitMQ的ack机制

    1.什么是消息确认ACK. 答:如果在处理消息的过程中,消费者的服务器在处理消息的时候出现异常,那么可能这条正在处理的消息就没有完成消息消费,数据就会丢失.为了确保数据不会丢失,RabbitMQ支持消 ...