当前位置:首页 > 问答 > 正文

数据库性能提升那些事儿,聊聊Oracle表字段索引怎么用更顺手

说到数据库性能提升,尤其是Oracle,有一个话题是怎么也绕不开的,那就是索引,这东西用好了,就像给数据库装上了火箭推进器,查询速度嗖嗖的;但要是用不好,反而会成为累赘,拖慢数据更新的速度,今天咱们就不聊那些高深莫测的理论,就聊聊怎么把表字段索引用得顺手,像用筷子一样自然。

得弄明白索引到底是个啥。

你可以把数据库表想象成一本非常厚的电话簿,里面记录了所有人的信息(姓名、电话、地址),如果没有索引,当你想找“张三”的电话时,你只能从第一页开始,一页一页地翻,这就是所谓的“全表扫描”,如果这本书有几百万页,那得找到什么时候?

索引呢,就像这本电话簿最前面的按姓氏拼音排序的目录,你想找“张三”,直接翻到“Z”开头的部分,很快就能定位到“张”姓所在的页码范围,然后去那个小范围里稍微一找就找到了,这个“目录”就是索引,它通过额外的空间(就像书前面的目录也占页数一样),存储了某个字段(姓名”)和对应数据位置的映射关系,让查询变得极快。

问题来了,给哪些字段建索引最划算?

这里有个黄金法则:高选择性字段优先,啥叫高选择性?就是这个字段的值在表里几乎都是唯一的,或者重复值非常少,身份证号”、“手机号”、“订单号”这种,你查一个身份证号,最多就返回一条记录,索引的效果立竿见影。

反过来,像“性别”这种字段,就只有“男”、“女”两个值(我们暂不讨论其他情况),你给它建个索引,一查“男”,可能返回一半的数据,数据库优化器一看,用索引还得来回折腾定位那么多行,还不如直接全表扫描快呢!这种索引建了也白建,反而在插入、更新数据时还要维护这个没用的索引,得不偿失。

聊聊几种常见的顺手用法。

查询条件里经常出现的字段,一定要考虑。 这是最基本的原则,如果你的应用里动不动就根据“客户ID”来查订单,或者根据“创建时间”范围查日志,那就在“客户ID”和“创建时间”上建索引,这几乎是送分题。

联合索引(也叫组合索引)的学问大了去了。 我们经常会用两个或多个字段一起查,根据城市和薪资水平找人才”,这时候,你可以创建一个联合索引,INDEX(city, salary),这里有个关键点:顺序很重要,这个索引相当于一本先按城市排序,同一个城市里再按薪资排序的目录。

  • 顺手用法:如果你的查询条件是 WHERE city='北京' AND salary>10000,这个索引就非常高效,因为它能快速定位到“北京”,然后在“北京”内部按薪资找。
  • 不顺手用法:但如果你的查询条件只有 WHERE salary>10000,这个索引就基本失效了,因为索引的第一级是“城市”,你跳过城市直接查薪资,数据库还是得扫描所有城市下的所有薪资记录,相当于又回到了全表扫描,联合索引的顺序,要和你最常用的查询条件顺序匹配,有个简单的原则叫“最左前缀原则”,就是说查询条件必须从联合索引的最左边字段开始用起,才能高效。

别再对索引字段做计算或者函数操作。 这是一个很容易掉进去的坑,比如你有个日期字段 create_time,你给它建了索引,但你的查询语句写成了: WHERE TO_CHAR(create_time, 'YYYY-MM-DD') = '2023-10-01' 这下坏了,索引大概率会失效,因为数据库没办法直接拿 ‘2023-10-01’ 这个字符串去索引树里找,它必须先把表中每一行的 create_time 都转换成字符串格式,然后再去比较,这又导致了全表扫描,顺手的写法应该是: WHERE create_time >= TO_DATE('2023-10-01', 'YYYY-MM-DD') AND create_time < TO_DATE('2023-10-02', 'YYYY-MM-DD') 这样就能直接利用 create_time 字段上的索引了。

like查询的小技巧。 模糊查询 LIKE 用不好也会让索引失效,如果你经常用 LIKE ‘张%’ 这种前缀匹配(找所有姓张的人),索引是有效的,因为“张”是明确的起点,但如果你用 LIKE ‘%三’(找所有名字以“三”结尾的人)或者 LIKE ‘%三%’(找名字中带“三”的人),索引就无能为力了,因为不知道从哪里开始找,如果这种需求很频繁,可能需要考虑使用Oracle的文本索引(Text Index)等更高级的功能。

别忘了索引也是有代价的。

索引不是越多越好,每多一个索引,就像给那本电话簿多做了一个目录,当有新电话登记(INSERT)或者有人换了地址(UPDATE)、换了电话(UPDATE)、注销了号码(DELETE)时,你不仅要把信息录入主册子,还得去更新每一个“目录”(索引),索引越多,这些写操作的速度就越慢。

建索引的本质是一场权衡(Trade-off),用空间和写性能的代价,来换取读查询的速度,你需要根据自己业务的实际情况——是读多写少还是写多读少,哪些查询最频繁、最慢——来做出最顺手的选择,定期审视一下你的索引,看看哪些很久没用(Oracle有监控索引使用的功能),果断删掉那些“僵尸索引”,才能让数据库始终保持轻快。

把索引用顺手,关键就三点:选对字段、理解顺序、避免破坏,多观察你的SQL语句,多分析执行计划,慢慢你就会找到感觉,像老司机一样驾驭Oracle的索引了。 参考了Oracle官方文档中关于索引的基础概念、以及《Oracle高效设计》等经典书籍中关于索引使用的实践经验,并结合了常见的数据库优化实践总结。)

数据库性能提升那些事儿,聊聊Oracle表字段索引怎么用更顺手