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

后浪云OceanBase里说说怎么用DROP INDEX删掉索引那些事儿

(引用来源:OceanBase官方文档中关于DROP INDEX的说明)

在OceanBase数据库里,当你觉得某个索引已经没用了,比如它拖慢了数据写入的速度,或者当初创建它的目的已经不存在了,你就可以考虑把它删掉,删除索引的这个操作,用的就是一个叫做DROP INDEX的命令,这个命令本身看起来很简单,但里面有些细节和需要注意的地方,咱们来详细说说。

最基础、最直接的用法就是这样:

DROP INDEX 索引名字 ON 表名字;

就这么一行命令,比如说,你有一张表叫做employee(员工表),你之前为了能快速按照员工姓名查找,给name这个字段建了一个索引,取名叫idx_employee_name,现在你觉得这个索引没必要了,想删掉它,那你就可以在数据库的连接工具里(比如OBClient或者其他的图形化界面)执行这么一句:

DROP INDEX idx_employee_name ON employee;

执行完了,这个索引就从employee表上被移除了,之后你再往表里插入新数据,或者更新数据的时候,数据库就不用再费劲去维护这个索引了,可能会感觉快一点,这个索引占用的存储空间也会被释放出来。

(引用来源:OceanBase官方文档中关于DROP INDEX的权限和表类型部分)

事情往往没那么简单,第一个要注意的是,你不是随便谁都能执行这个命令的,你得有权限,你必须是这个表的主人(也就是属主),或者数据库管理员(DBA)给你赋予了删除这个表上索引的权限才行,如果你没有权限,硬要去删,数据库会直接告诉你“权限不够”,然后拒绝执行。

第二个要注意的是,你是在哪种表上删索引,OceanBase里有两种主要的表类型,一种叫非分区表,就是整张表是一个整体的;另一种叫分区表,就是把一张大表像切蛋糕一样分成很多个小块(分区)来存储,目的是为了管理方便和查询更快,在非分区表上删索引,就像我们上面说的那样,直接用那个命令就行了,比较简单,但如果你是在分区表上操作,那就有更多选择了,这也是OceanBase作为一个分布式数据库的特色之一。

(引用来源:OceanBase官方文档中关于在分区表上删除索引的语法)

对于分区表,DROP INDEX命令提供了更灵活的选项,你可以选择只删除某个特定分区上的索引,而不是整个表的索引,它的语法长这样:

DROP INDEX 索引名字 ON 表名字 PARTITION (分区名字);

举个例子,你的employee表可能不是一张普通的表,而是一张分区表,按照员工入职的年份进行了分区,比如有p2020, p2021, p2022这几个分区,你之前在整个表上创建了一个索引idx_employee_salary(薪水索引),现在呢,你可能觉得2020年以前的员工数据几乎不再查询了,但为了合规又不能删除那些数据,可是维护2020年分区的索引又浪费资源,这时候,你就可以精确地只删除p2020这个分区上的索引,而保留其他分区的索引,命令就是这样:

DROP INDEX idx_employee_salary ON employee PARTITION (p2020);

执行这个命令后,只有p2020分区上的idx_employee_salary索引被删掉了,p2021p2022分区上的这个索引还完好无损,针对这些新数据的快速查询依然有效,这种精细化的操作在管理海量数据时非常有用,可以帮你节省很多不必要的开销。

(引用来源:OceanBase官方文档中关于删除索引的注意事项和影响)

说完了怎么删,咱们再聊聊删索引之前你得想清楚的那些事儿,最重要的一点是,删除索引是一个无法撤销的操作,不像你在电脑上删个文件还能从回收站里找回来,在数据库里执行了DROP INDEX之后,这个索引就真的没了,在执行之前,一定要百分之百确定这个索引确实是不再需要了,怎么确定呢?你可以想想:

  1. 还有没有业务程序或者经常跑的查询语句依赖这个索引来加速?如果你删了,会不会导致某些查询突然变得特别慢?
  2. 这个索引是不是有某种特殊的约束作用?(虽然更常见的是用主键或唯一约束,但索引有时也和相关)。
  3. 最好能和开发人员或者团队里的其他成员沟通一下,确保大家都同意删除。

一个比较稳妥的做法是,在决定删除一个不确定的索引之前,可以先“禁用”它看看效果,需要注意的是,在OceanBase的当前版本中,并没有像一些其他数据库那样直接提供一个ALTER INDEX ... UNUSABLE这样的命令来禁用索引,更常见的做法是,如果你不确定,可以先在测试环境或者一个不重要的业务时间段,模拟真实的生产负载,然后删除索引,观察一段时间,看看对系统性能和业务查询有没有负面影响,如果一切正常,再到生产环境去操作。

删除索引这个操作本身也会对数据库产生一点短暂的影响,因为在删除的过程中,数据库需要获取表上的一个锁,以确保在删除索引的这一刻,没有其他操作在同时修改这个表的数据,如果这个表非常大,或者当时正有非常多的数据写入、更新操作,这个锁可能会导致其他会话稍微等待一下,选择一个业务低峰期(比如深夜或者访问量少的时候)来执行这种维护操作,是一个好习惯。

再强调一下命令的写法,索引名和表名一定要写对,大小写要和你创建的时候保持一致(通常OceanBase默认是不区分大小写的,但最好还是保持一致),分区名也要准确,如果写错了,比如表名拼错了,数据库会报错说“表不存在”;如果索引名拼错了,会报错说“索引不存在”,这都是帮你检查的好机会。

在OceanBase里用DROP INDEX删索引,核心命令就那一行,但关键在于操作之前的思考:有没有权限?是在什么类型的表上操作?是否需要精确到分区?删除后会不会有未知影响?确保都想清楚了,再在合适的时间点执行,这样就能安全、高效地管理你的索引了。


后浪云OceanBase里说说怎么用DROP INDEX删掉索引那些事儿