我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。
解锁数据库查询新姿势:函数索引让你的搜索又快又准
你是否遇到过这样的情况:在数据库中搜索用户名时,希望不区分大小写,但查询速度却慢得让人抓狂?或者想要基于复杂计算的结果来快速查找数据,却不知道如何实现?这就是函数索引大显身手的时候了!
什么是函数索引?
简单来说,函数索引允许我们对计算后的列值创建索引,而不仅仅是原始数据列。比如,你可以创建一个基于"大写转换后姓名"的索引,从而实现不区分大小写的快速搜索。
为什么需要函数索引?
- 实现简单,见效快 - 只需创建一个索引,现有查询就能立即加速
- 零代码修改 - 无需改动现有应用程序逻辑或查询语句
- 扩展SQL能力 - 可以基于自定义函数创建索引,实现特殊搜索需求
实战案例:不区分大小写的搜索
假设我们有一个员工表(EMP),需要按姓名搜索但不区分大小写。
传统方法的困境
在过去,要实现这个功能需要:
- 添加一个额外列(如UPPER_ENAME)
- 编写触发器在插入/更新时自动填充这个列
- 为这个新列创建索引
这种方法既麻烦又增加了维护成本。
函数索引的优雅解决方案
现在只需一步就能搞定:
CREATE INDEX emp_upper_idx ON emp(UPPER(ename));
创建这个索引后,任何使用WHERE UPPER(ename) = 'KING'的查询都会自动使用索引,速度极快!
更强大的应用:自定义函数索引
有时候我们需要更复杂的搜索逻辑。比如,实现一个自定义的语音搜索功能(类似Soundex算法)。
创建自定义函数
首先,我们创建一个将文字转换为语音代码的函数:
CREATE OR REPLACE FUNCTION my_soundex(p_string IN VARCHAR2)
RETURN VARCHAR2 DETERMINISTIC
AS
-- 函数实现细节
BEGIN-- 将输入字符串转换为语音代码RETURN l_return_string;
END;
/
注意这里的DETERMINISTIC关键字很重要,它告诉Oracle:相同输入总是产生相同输出,这是创建函数索引的前提。
创建函数索引
由于函数返回的是字符串,我们需要使用SUBSTR来限制索引大小:
CREATE INDEX emp_soundex_idx ON emp(SUBSTR(my_soundex(ename), 1, 6));
性能对比
让我们看看使用函数索引前后的性能差异:
没有索引时:
- 查询时间:约0.2秒
- 函数被调用:9916次(几乎每行一次)
- 需要全表扫描
有索引后:
- 查询时间:约0.01秒(提升20倍!)
- 函数被调用:仅1次
- 使用索引范围扫描
虽然插入数据时稍微慢了一点(0.30秒→0.57秒),但查询性能的提升远远超过了这点代价。毕竟,数据一次插入,却要多次查询!
让使用更简单:隐藏复杂性
直接使用SUBSTR(my_soundex(ename), 1, 6)这样的表达式既不方便又容易出错。我们可以通过两种方式简化:
方法一:使用视图
CREATE OR REPLACE VIEW emp_v AS
SELECT ename, SUBSTR(my_soundex(ename), 1, 6) ename_soundex, hiredate
FROM emp;
然后就可以简单地查询:WHERE ename_soundex = my_soundex('Kings')
方法二:使用虚拟列(更推荐)
-- 添加虚拟列
ALTER TABLE emp ADD ename_soundex AS (SUBSTR(my_soundex(ename), 1, 6));-- 为虚拟列创建索引
CREATE INDEX emp_soundex_idx ON emp(ename_soundex);
这样就能直接查询:WHERE ename_soundex = my_soundex('Kings'),既简单又高效!
总结
函数索引是数据库性能优化的利器,特别适合以下场景:
- 不区分大小写的搜索
- 基于复杂计算的查询
- 使用自定义函数的特殊搜索需求
虽然创建函数索引会让数据插入稍慢一些,但查询性能的提升是巨大的。对于大多数读多写少的应用场景来说,这种权衡是非常值得的。
记住两个关键点:
- 函数必须是DETERMINISTIC(确定性的)
- 对于返回字符串的函数,使用SUBSTR控制索引大小
现在就试试函数索引吧,让你的数据库查询又快又准!
------------------作者介绍-----------------------
姓名:黄廷忠
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)