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. Java播放MP3播放音频

    Java播放MP3播放音频 下面我演示用jdk自带包.框架等分别展示播放mp3.等music 一.使用javafx包 AudioClip 注意jdk11以上剥离了javafx public stati ...

  2. 【Python】人工智能-机器学习——不调库手撕深度网络分类问题

    1. 作业内容描述 1.1 背景 数据集大小150 该数据有4个属性,分别如下 Sepal.Length:花萼长度(cm) Sepal.Width:花萼宽度单位(cm) Petal.Length:花瓣 ...

  3. 2天完成17TB数据量迁移,华为云数据库是如何做的?

    摘要:童年时候,我们会对着墙上挂着的中国地图,来认识一处处山川河流和城市人文.如今,数字化时代下,传统的地图已经不能满足人们的需求,如何获取各种丰富的地理内容和实时动态信息成为现代人普遍的地理信息诉求 ...

  4. 一文读懂火山引擎A/B测试的实验类型(1)——编程实验

    一. 概述 编程实验:指的是通过代码编程进行AB实验,广泛使用于前端优化.策略优化和后端算法优化多种实验场景,包含客户端和服务端实验. 前置条件:接入客户端SDK或者服务端SDK,详见:应用接入 二. ...

  5. Solon2 开发之IoC,六、提取 Bean 的函数进行定制开发

    为什么需要提取Bean的函数?绝不是闲得淡疼.比如:控制器的@Mapping:再比如:Xxl-Job的@XxlJob.这些都是要提取Bean的函数并定制加工的. 1.比如提取 @XxlJob 注解的函 ...

  6. Chrome 英文翻译插件,沙拉查词

    下载: https://pan.baidu.com/s/1VRaZzKgyPKc0Qt6Gufk3yw 提取码: chbm 下载: https://pan.baidu.com/s/1VRaZzKgyP ...

  7. 微服务网关 —— SpringCloud Netflix Zuul

    概述 Spring Cloud Zuul 是 Spring Cloud Netflix 子项目的核心组件之一,可以作为微服务架构中的 API 网关使用,有以下用途: 鉴权:对于访问每个服务的请求进行鉴 ...

  8. 背景 | 基于 Transformers 的编码器-解码器模型

    !pip install transformers==4.2.1 !pip install sentencepiece==0.1.95 Vaswani 等人在其名作 Attention is all ...

  9. Linux day3:⽹络不通排查流程 linux重要数据文件 系统优化相关 上传下载 文件权限 所属用户及用户组

    目录 ⽹络不通排查流程 linux重要数据文件 etc⽬录下重要的数据⽂件 usr⽬录下重要的数据⽂件 var⽬录下重要的数据⽂件 proc⽬录重要的数据⽂件 系统优化相关 环境变量 下载软件优化操作 ...

  10. ChatGpt windows+mac os+linux三平台桌面版下载

    1 前言 ChatGPT这段时间还是挺火的,有不了解的小伙伴可以看看这篇ChatGPT为何打响AI新时代的礼炮,一路火花带闪电[1],能简单的了解: 什么是ChatGPT ChatGPT为什么这么火 ...