KingbaseES 语句like前匹配如何使用索引
前言
有现场同事反馈 sql语句 like 使用后缀通配符 % 不走索引。
至于执行计划没走索引的原因与KingbaseES数据库中的排序规则相关。
测试
测试环境:
KingbaseESV8R6C7
test=# \d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | text | | |
Indexes:
"test_id" btree (id)
"test_name" btree (name)
insert into test select generate_series(1,1000000), generate_series(1,1000000)||'tt';
test=# select count(*) from test;
count
----------
1000000
(1 row)
执行计划没走索引
test=# explain analyze select * from test where name like '99999%';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.00..11653.33 rows=100 width=12) (actual time=0.261..75.993 rows=11 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Parallel Seq Scan on test (cost=0.00..10643.33 rows=42 width=12) (actual time=30.369..55.302 rows=4 loops=3)
Filter: (name ~~ '99999%'::text)
Rows Removed by Filter: 333330
Planning Time: 0.051 ms
Execution Time: 76.046 ms
(8 rows)
--关闭全表扫后,执行计划仍不走索引
test=# set enable_seqscan = off;
SET
test=# explain analyze select * from test where name like '99999%';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Seq Scan on test (cost=10000000000.00..10000017935.00 rows=100 width=12) (actual time=0.133..67.511 rows=11 loops=1)
Filter: (name ~~ '99999%'::text)
Rows Removed by Filter: 999989
Planning Time: 0.077 ms
Execution Time: 67.552 ms
(5 rows)
在KingbaseES数据库中的特性:只有在数据库 Collate 为 C 时,like 使用后缀通配符(%)时,才会用到索引。
如下所示,test库,上述为 Collate 为 zh_CN.UTF-8 时的示例,
test=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+--------+----------+-------------+-------------+-------------------
security | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
template0 | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/system +
| | | | | system=CTc/system
template1 | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/system +
| | | | | system=CTc/system
test | system | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =Tc/system +
| | | | | system=CTc/system+
| | | | | u1=c/system +
| | | | | u2=c/system
(6 rows)
下面看下Collation为 C 时的测试示例
alter table test alter name type text COLLATE "c";
test=# \d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | text | c | |
Indexes:
"test_id" btree (id)
"test_name" btree (name)
执行计划走索引
test=# explain analyze select * from test where name like '99999%';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=127.67..5733.52 rows=5000 width=36) (actual time=0.018..0.022 rows=11 loops=1)
Filter: (name ~~ '99999%'::text)
Heap Blocks: exact=2
-> Bitmap Index Scan on test_name (cost=0.00..126.42 rows=5000 width=0) (actual time=0.011..0.011 rows=11 loops=1)
Index Cond: ((name >= '99999'::text) AND (name < '9999:'::text))
Planning Time: 0.183 ms
Execution Time: 0.037 ms
(7 rows)
以上是通过修改表列的排序规则实现该列的索引的使用,还可以通过创建数据库时指定排序规则,或者创建表时指定排序规则。
参考博客园文档:https://www.cnblogs.com/kingbase/p/16743713.html
测试另一种方式:
1) 创建索引时,加上对应字段类型的操作符
--重建索引
test=# \d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | text | en_US | |
Indexes:
"test_id" btree (id)
"test_name" btree (name)
test=# drop index test_name;
DROP INDEX
test=# create index test_name on test(name varchar_pattern_ops);
CREATE INDEX
test=# \d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | text | en_US | |
Indexes:
"test_id" btree (id)
"test_name" btree (name varchar_pattern_ops)
执行计划可以走索引
test=# explain analyze select * from test where name like '99999%';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=127.67..5733.52 rows=5000 width=36) (actual time=0.018..0.022 rows=11 loops=1)
Filter: (name ~~ '99999%'::text)
Heap Blocks: exact=2
-> Bitmap Index Scan on test_name (cost=0.00..126.42 rows=5000 width=0) (actual time=0.011..0.011 rows=11 loops=1)
Index Cond: ((name ~>=~ '99999'::text) AND (name ~<~ '9999:'::text))
Planning Time: 0.218 ms
Execution Time: 0.037 ms
(7 rows)
操作符text_pattern_ops、varchar_pattern_ops、bpchar_pattern_ops 分别支持类型 text、varchar 和 char 上的B树索引。
它们与默认操作符类的区别是值的比较是严格按照字符进行而不是根据其他相关的排序规则。
这使得这些操作符类适合于当一个数据库没有使用标准“C”区域时被使用在涉及模式匹配表达式(LIKE 或 POSIX 正则表达式)的查询中。
2)另一种创建索引方式:创建索引时指定排序规则
test=# drop index test_name;
DROP INDEX
test=# create index test_name on test(name collate "c");
CREATE INDEX
test=# \d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | text | en_US | |
Indexes:
"test_id" btree (id)
"test_name" btree (name COLLATE c)
执行计划也可以走索引
test=# explain analyze select * from test where name like '99999%';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=127.67..5733.52 rows=5000 width=36) (actual time=0.020..0.024 rows=11 loops=1)
Filter: (name ~~ '99999%'::text)
Heap Blocks: exact=2
-> Bitmap Index Scan on test_name (cost=0.00..126.42 rows=5000 width=0) (actual time=0.012..0.013 rows=11 loops=1)
Index Cond: ((name >= '99999'::text) AND (name < '9999:'::text))
Planning Time: 0.153 ms
Execution Time: 0.051 ms
(7 rows)
3)正则表达式写法走索引
test=# \d test
Table "public.test"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
name | text | en_US | |
Indexes:
"test_id" btree (id)
"test_name" btree (name)
test=# explain analyze select * from test where name like '^99999';
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=115.17..5721.02 rows=5000 width=36) (actual time=0.033..0.033 rows=0 loops=1)
Filter: (name ~~ '^99999'::text)
-> Bitmap Index Scan on test_name (cost=0.00..113.92 rows=5000 width=0) (actual time=0.031..0.031 rows=0 loops=1)
Index Cond: (name = '^99999'::text)
Planning Time: 0.088 ms
Execution Time: 0.048 ms
(6 rows)
总结
遇到like通配符,执行计划显示不走索引的情况,首先查看索引列,表,数据库对应的排序规则Collation,然后根据以上测试示例进行现场实测并变更排序规则。
相关文档:https://www.cnblogs.com/kingbase/p/16743713.html
KingbaseES 语句like前匹配如何使用索引的更多相关文章
- like语句百分号前置会使用到索引吗?
like语句百分号前置会使用到索引吗? 前几天看了这篇文章:谈SQL Server对like '%关键词%' 处理时的索引利用问题 看完了之后,我很想知道这篇文章是不是临时工写的?还是网站的主人写的, ...
- 面试题--如何防止sql注入,使用PreparedStatement的预编译,传入的内容就不会和原来的语句发生任何匹配的关系,达到防止注入的方法
PreparedStatement的用法 jdbc(java database connectivity,java数据库连接)的api中的主要的四个类之一的java.sql.statement要求开发 ...
- 两个字符串,s1 包含 s2,包含多次,返回每一个匹配到的索引---python
#两个字符串,s1 包含 s2,包含多次,返回每一个匹配到的索引 def findSubIndex(str1,subStr): str_len = len(str1) sub_len = len(su ...
- sql语句中like匹配的用法详解
在SQL结构化查询语言中,LIKE语句有着至关重要的作用. LIKE语句的语法格式是:select * from 表名 where 字段名 like 对应值(子串),它主要是针对字符型字段的,它的作用 ...
- 【转】同一个SQL查询语句,为什么使用到的索引不同?
问: 同一个SQL查询语句,只是修改where条件中的一个值,为什么使用到的索引情况也会不同?谢谢! 1) explain执行结果,如下图: 2) 表中的数据如下图: 3) 表结构如下图: 4) 创建 ...
- uploadPreview 上传图片前预览 IE9 索引无效的问题
最近公司的项目用到比较多的上传图片的操作,所以用到了基于jquery的上传前预览的插件 uploadPreview ,后来测试的时候发现在IE9下报索引无效的问题. 异常的产生方式 放一个file控件 ...
- finall语句是在return语句执行前被执行还是执行后被执行?
finally对try...catch的影响和执行时间 一.finally语句不被执行的两种情况 我们在学习抛出异常的时候学习到了finally语句块,这个语句块一般会被执行,但是有两种情况下不被执行 ...
- 数据库char varchar nchar nvarchar,编码Unicode,UTF8,GBK等,Sql语句中文前为什么加N(一次线上数据存储乱码排查)
背景 公司有一个数据处理线,上面的数据经过不同环境处理,然后上线到正式库.其中一个环节需要将数据进行处理然后导入到另外一个库(Sql Server).这个处理的程序是老大用python写的,处理完后进 ...
- Java开发学习(四十五)----MyBatisPlus查询语句之映射匹配兼容性
1.映射匹配兼容性 我们已经能从表中查询出数据,并将数据封装到模型类中,这整个过程涉及到一张表和一个模型类: 之所以数据能够成功的从表中获取并封装到模型对象中,原因是表的字段列名和模型类的属性名一样. ...
- mysql语句插入前判断数据是否重复
在mysql中插入数据有时需要判断数据插入是否重复 语句编写:insert into 表(相应字段) select 相应字段 from dual where not exists (select 相应 ...
随机推荐
- 【Unity3D】Renderer Feature简介
1 3D 项目迁移到 URP 项目后出现的问题 3D 项目迁移至 URP 项目后,会出现很多渲染问题,如:材质显示异常.GL 渲染不显示.多 Pass 渲染异常.屏幕后处理异常等问题.下面将针对这 ...
- SpringBoot+Shiro+LayUI权限管理系统项目-2.业务模型分析
1.项目模型介绍 1.1 部门表 部门编码.部门名称.上级部门 1.2 角色表 角色编码.角色名称 1.3 权限表 权限名称.权限标识.权限类型.上级权限.URL.权限图标.是否外部打开 1.4 用户 ...
- Java Swing实现五子棋程序
首先感谢08年MLDN出的这个培训视频,我把代码和文档整理了一下,发布出来给需要学习Swing的朋友. 源码地址: https://gitee.com/indexman/gobang 一.知识点准备: ...
- Java I/O 教程(七) DataOutputStream和DataInputStream
Java DataOutputStream Class Java DataOutputStream class 可以以机器无关方式往指定输出流写入Java原始数据类型,例如int, double, l ...
- Java 使用 itext 向PDF插入数据和图片
Java 使用 itext 向PDF插入数据和图片 一.下载Adobe Acrobat DC 二.制作模板 1.准备一个word模板,并转换成PDF格式 2.使用Adobe Acrobat DC打开P ...
- React 组件懒加载
只有不断学习和成长,才能适应这个快速变化的世界. 1. 懒加载 1.1 React 懒加载 React 中懒加载 Lazy 与 Suspense 需要搭配使用. React.lazy 定义: Reac ...
- DataGear 制作支持表单交互和多图表联动的数据可视化看板
对于数据可视化,有时需要根据用户输入的查询条件展示限定范围的数据图表,DataGear的看板表单功能可以快速方便地实现此类需求. 下面的看板示例,包含一个柱状图.一个饼图和一个地图,用户可以通过看板表 ...
- 【Azure 应用服务】登录App Service 高级工具 Kudu站点的 Basic Auth 方式
问题描述 从Azure App Service的页面中,直接跳转到高级管理工具Kudu站点(https://<your app service name>.scm.chinacloudsi ...
- [java] Tomcat 启动失败 Error: error while reading constant pool for .class: unexpected tag at #
表现 公司服务器今天启动tomcat失败, 看catalina.out文件里面报错 java.lang.ClassFormatError: Unknown constant tag 101 in cl ...
- SSH原理与实践(二)
主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 在上一篇文章[ssh原理与实践(一)]中我们详细介绍了SSH两种 ...