函数索引跟普通索引谁的效率高

本文通过实验对比了在不同查询结果数量下,Oracle数据库中函数索引与普通索引的性能差异。结果显示,当返回结果较少时,普通索引更优;反之,函数索引则表现出更好的性能。

环境:oracle 11g


在sqlplus中开启:

set  linesize 500

set autotrace traceonly

set timing on

这里用Substr和 'xxx%'的查询效率做测试


drop table t purge;

create table t as

select * from  dba_objects;

--实验1:返回多数据

--预计3313条记录

--加普通索引

create index t_object_type_idn on t(object_type);

select * fromwhere t.object_type like 'TAB%';


--加函数索引

drop index t_object_type_idn;

create index t_object_type_idn_fun on t(substr(t.object_type,1,3));

 

select * fromwhere  substr(t.object_type,1,3)='TAB';


发现:代价:函数索引小于普通索引


实验2:返回少数据100

drop table t purge;

create table t as

select * from  dba_objects;

 

update t set t.object_type='XXXAAA' where rownum<=100;

--加普通索引

create index t_object_type_idn on t(object_type);

select * fromwhere t.object_type like 'XXX%';



--加函数索引

drop index t_object_type_idn;

create index t_object_type_idn_fun on t(substr(object_type,1,3));

 

select * fromwhere  substr(t.object_type,1,3)='XXX';


发现:代价:函数索引大于普通索引


实验3:找到函数索引与普通索引性能差不多时的记录数;400

 

drop table t purge;

create table t as

select * from  dba_objects;

 

update t set t.object_type='XXXAAA' where rownum<=400;

--加普通索引

create index t_object_type_idn on t(object_type);

select * fromwhere t.object_type like 'XXX%';



--加函数索引

drop index t_object_type_idn;

create index t_object_type_idn_fun on t(substr(object_type,1,3));

 

select * fromwhere  substr(t.object_type,1,3)='XXX';



小结:发现平衡点在400左右;

当查询的结果数量小于400时,普通索引的性能高于函数索引;

当查询的结果数量大于400时,函数索引性能高于普通索引;

 

这里仅使用了dba_objectsz作为测试,实际的不同表临界值可能不一样;


### 创建和使用带函数索引 对于带有函数索引,在某些数据库管理系统中被称为函数索引或者表达式索引。这类索引允许基于一列或多列上的特定函数或表达式的返回值来构建索引,从而提高涉及这些复杂查询条件下的检索效率[^1]。 #### 函数索引的作用范围 当SQL语句中的WHERE子句包含了对某字段应用了相同函数的情况时,如果存在针对该字段及其对应函数建立起来的函数索引,则可以被利用到;反之,普通的B树型单列索引无法在这种情况下发挥作用。 #### MySQL下创建函数索引的方法 在MySQL 8.0及以上版本支持直接为表达式创建索引。语法如下所示: ```sql CREATE INDEX idx_name ON table_name ((expression)); ``` 这里`idx_name`代表新创建出来的索引名称,而`table_name`则是要为其添加索引的数据表名,最后括号内的部分则表示用于构成此索引的具体表达式[^2]。 例如,假设有一个名为`employees`的数据表,并且经常需要按照员工姓名的大写形式进行查找操作,此时就可以考虑为此种需求专门设计一个函数索引来加速此类查询的速度: ```sql -- 假设 employees 表中有 name 字段存储的是小写的员工名字 CREATE INDEX upper_name_idx ON employees ((UPPER(name))); ``` 上述命令将会依据`name`列上调用`UPPER()`函数的结果生成一个新的索引项,之后再遇到形如`SELECT * FROM employees WHERE UPPER(name)= 'SMITH'`这样的查询请求时就能有效命中并运用到这条新建好的索引路径上来完成快速定位记录的任务了。 #### 使用场景分析 通常来说,只要是在业务逻辑里频繁涉及到某个固定模式的操作(比如字符串大小写转换、日期格式化等),都可以尝试通过引入相应的函数索引来改善整体性能表现。不过值得注意的一点在于并不是所有的内置函数都适合用来做这种处理——具体哪些是可以接受作为参数传递给CREATE INDEX语句里的取决于所使用的DBMS平台本身的支持程度以及内部实现机制等因素影响。 #### 性能优化建议 为了确保最佳效果,在规划阶段应当充分考虑到以下几个方面: - **选择合适的函数**:并非所有类型的运算符或是自定义过程都能够成为有效的候选对象; - **评估数据分布特性**:只有那些具有较高区分度特征的目标集才值得为之付出额外开销去维护这样一个特殊结构; - **定期重构低效索引**:随着应用程序的发展变化,原先设定的一些规则可能会逐渐变得不再适用甚至拖累系统响应速度,因此适时调整策略十分必要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值