以通配符(%)开始的like字符串,走索引
在对oracle的SQL优化过程中经常会遇到【like'%abc'】破坏索引的问题,但是如果真有此类需求,该如何在不破坏索引的基础上进行查询呢。
[sql] view plain copy
sys@mescp> select reverse('') from dual; REVERSE('')
-------------------------------- row selected. sys@mescp> create table test_like as select object_id,object_name from dba_objects; Table created. sys@mescp> create index test_like__name on test_like(object_name); Index created. sys@mescp> create index test_like__name_reverse on test_like(reverse(object_name)); Index created. sys@mescp> analyze table test_like compute statistics for table for all indexes; Table analyzed. sys@mescp> set autotrace trace exp -- '常量开头的like , 会利用index ,没问题…… ' sys@mescp> select * from test_like where object_name like AS%'; Execution Plan ----------------------------------------------------------
SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes=)
TABLE ACCESS (BY INDEX ROWID) OF 'TEST_LIKE' (Cost= Card=655Bytes=)
INDEX (RANGE SCAN) OF 'TEST_LIKE__NAME' (NON-UNIQUE) (Cost= Card=)
--'开头和结尾都是 % ,对不起,很难优化'
sys@mescp> select * from test_like where object_name like '%%'; Execution Plan ----------------------------------------------------------
SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes=)
TABLE ACCESS (FULL) OF 'TEST_LIKE' (Cost= Card= ytes=) -- '以常量结束,直接写的时候是不能应用index的'
sys@mescp> select * from test_like where object_name like '%S';
Execution Plan
----------------------------------------------------------
SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes=) TABLE ACCESS (FULL) OF 'TEST_LIKE' (Cost= Card= Bytes=)
--'以常量结束的,加个reverse 函数,又可以用上index了' sys@mescp> select * from test_like where reverse(object_name)like reverse('%AS');
Execution Plan ---------------------------------------------------------- SELECT STATEMENT Optimizer=CHOOSE (Cost= Card= Bytes=)
TABLE ACCESS (BY INDEX ROWID) OF 'TEST_LIKE' (Cost= Card= Bytes=) INDEX (RANGE SCAN) OF 'TEST_LIKE__NAME_REVERSE' (NON-UNIQUE) (Cost= Card=)
了解SQL的同学,都知道,like关键字可以走索引,只要字符串不是以通配符(%)开始。
如果类似 like "%xxx" 的sql,如何走索引呢?基于REVERSE()函数来创建一个函数索引。
1、准备数据:
CREATE TABLE jka AS SELECT ROWNUM id, dbms_random.string('x',10) v FROM dual CONNECT BY LEVEL <= 10000;
2、创建原始索引:
CREATE INDEX jka_normal ON jka (v); BEGIN
dbms_stats.gather_table_stats
(USER
,'JKA'
,estimate_percent=>100
,cascade=>TRUE);
END;
3、以下SQL基于jka_normal索引走范围扫描:
SELECT * FROM jka WHERE v LIKE 'ABC%';
4、但是下面的SQL将走全表扫描(不会使用索引):
SELECT * FROM jka WHERE v LIKE '%ABC';
5、现在,创建一个函数索引(不要与反向索引[REVERSE INDEX]混淆):
CREATE INDEX jka_reverse ON jka(REVERSE(v)); BEGIN
dbms_stats.gather_table_stats
(USER
,'JKA'
,estimate_percent=>100
,cascade=>TRUE);
END;
6、下面的SQL将基于jka_reverse索引走范围扫描:
SELECT * FROM jka WHERE REVERSE(v) LIKE REVERSE('%ABC');
问题解决。
以通配符(%)开始的like字符串,走索引的更多相关文章
- oracle数据库使用hint来让模糊查询走索引
在没有创建数据直方图之前,查询优化器是cbo,可能不会选择代价最低(效率最高)的方式查询. 先创建表 --日语假名表 CREATE TABLE JAPANESE_SOUNDMARK ( ID INTE ...
- 解决like '%字符串%'时索引不被使用的方法
解决like '%字符串%'时索引不被使用的方法 分步阅读 解决like '%字符串%'时索引不被使用的方法,如果like以通配符开头('%abc')时索引会失效会变成全表扫描的操作. 工具/原料 ...
- varchar int 查询 到底什么情况下走索引?
一个字符类型的.一个int类型的,查询的时候到底会不会走索引,其实很多工作了几年的开发人员有时也会晕,下面就用具体事例来测试一下. 1. 准备工作 先准备2张表,以备后续测试使用. 表1:创建表te ...
- 如何根据执行计划,判断Mysql语句是否走索引
如何根据执行计划,判断Mysql语句是否走索引
- 数据类型&字符串得索引及切片
一:数据类型 1):int 1,2,3用于计算 2):bool ture false 用于判断,也可做为if的条件 3):str 用引号引起来的都是str 存储少量数据,进行 ...
- mysql中关于关联索引的问题——对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引?
情况描述:在MySQL的user表中,对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引? 根据查询字段的位置不同来决定,如查询a, a,b a,b, ...
- sql查询未走索引问题分析之查询数据量过大
前因: 客户咨询,有一个业务sql(代表经常被执行且重要),全表扫描在系统占用资源很高(通过ash报告查询得到信息) 思路: 1.找到sql_text,sql_id 2.查看执行计划 3.查询sql涉 ...
- mysql 索引 create_time 加explain关键字是否走索引
SELECT * FROM t_user WHERE email='217@xxg.com'; --1.725 --加email索引之后 0.003 SELECT * FROM t_user WHE ...
- MySQL实现强制查询走索引和强制查询不缓存
0.表结构如下:(包含两个索引) Create Table: CREATE TABLE `user` ( `userID` ) NOT NULL, `userCode` ) DEFAULT NULL, ...
随机推荐
- 《天书夜读:从汇编语言到windows内核编程》六 驱动、设备、与请求
1)跳入到基础篇的内核编程第7章,驱动入口函数DriverEnter的返回值决定驱动程序是否加载成功,当打算反汇编阅读驱动内核程序时,可寻找该位置. 2)DRIVER_OBJECT下的派遣函数(分发函 ...
- vue-cli——vue-resource登录注册实例
前言 使用vue-resource请求接口非常方便,在使用前需安装vue-resource依赖并在入口文件main.js中声明. 实例功能简述 本实例只有简单的两个模块:登录和注册,主要演示如何用vu ...
- JavaScript数据可视化编程学习(二)Flotr2,雷达图
一.雷达图 使用雷达图显示多维数据. 如果你有多维的数据要展示,那么雷达图就是一种非常有效的可视化方法. 由于雷达图不常用,比较陌生,所以向用户解释的时候有一些难度.注意使用雷达图会增加用户认知负担. ...
- 关于vue 框架与后台框架的混合使用的尝试
这几天我在研究前台框架和后台框架融合的问题,进行了一些尝试; 我前台选择的是 vue,当然也可以选择 react 等其他 mvvm 框架,不过 vue 对于我来说是最熟悉的; 后台话,我选择的是 ph ...
- redux中间件的原理——从懵逼到恍然大悟
前言react已经出来很久了,其生态圈之庞大,一锅炖不下!各种react-xx,已让我们不堪重负,github上随便一个demo,引入的模块至少都是五指之数+.看着头疼,嚼之无味…….在此建议新学者, ...
- 基于文本图形(ncurses)的文本搜索工具 ncgrep
背景 作为一个VIM党,日常工作开发中,会经常利用grep进行关键词搜索,以快速定位到文件.如图: 利用grep进行文本搜索 但是,这一过程会有两个效率问题: 展示的结果无法进行直接交互,需要手动粘贴 ...
- RabbitMQ安装步骤
给centos安装epel yum 源 # rpm -ivh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.r ...
- video字幕无法显示,video视频在google中无法控制快进
video字幕(track)无法显示: 直接用关闭同源策略的浏览器打开你的HTML文件可以请求到字幕文件并显示字幕: 从hbuilder中打开html文件,在从里面打开google浏览器去浏览HTML ...
- node.js爬虫
这是一个简单的node.js爬虫项目,麻雀虽小五脏俱全. 本项目主要包含一下技术: 发送http抓取页面(http).分析页面(cheerio).中文乱码处理(bufferhelper).异步并发流程 ...
- java-8u151-64安装与配置环境变量
去oracle官网下载 java jdk for developments(最新发布的java9与java8有很大差别,选择8就够用了) 我是装在默认的C盘里的,直接配置环境变量了 新建JAVA_HO ...