删索引为什么要先检查
索引不只是查询加速:唯一索引通常承担 UNIQUE 约束,外键也要求被引用列上有索引。直接 DROP INDEX 可能顺手删掉业务约束,或者因为外键依赖而执行失败。正确顺序是先查清「谁在用这个索引、它承担什么角色」,再决定删除、改成普通索引还是保留。
基本信息
| MySQL 查看 | SHOW INDEX FROM 表 看索引名与唯一性 |
|---|---|
| PostgreSQL 查看 | pg_index 与 pg_constraint 查约束依赖 |
| 唯一索引 | 删除即失去唯一性保证 |
| 外键要求 | MySQL 外键需要被引用列上有索引,缺了无法删除 |
| 删除语法 | MySQL ALTER TABLE ... DROP INDEX;PG DROP INDEX 或 DROP CONSTRAINT |
典型使用场景
- 清理冗余或重复索引,降低写入维护开销
- 下线前做验证:先隐藏再删除
- 调整复合索引列序,先删旧索引再建新索引
- 解除误建的唯一约束,恢复正常写入
- 按慢写排查结果清理长期未使用的索引
MySQL 检查与删除
MySQL 检查与删除
SHOW INDEX FROM users; -- 看索引名、列顺序与 Non_unique 列
SHOW CREATE TABLE users; -- 看索引由哪条约束创建
-- 普通索引可以直接删除
ALTER TABLE users DROP INDEX idx_status;
-- 报 1553 说明它是外键所需索引,要先处理外键或换一个可覆盖的索引PostgreSQL 检查与删除
PostgreSQL 检查与删除
-- 查依赖该索引的约束
SELECT conname, contype
FROM pg_constraint
WHERE conindid = 'uk_users_email'::regclass;
-- 由约束创建的索引不能直接 DROP,须先删约束(索引随之消失)
ALTER TABLE users DROP CONSTRAINT uk_users_email;
-- 普通索引直接删
DROP INDEX idx_users_status;索引来源与删除方式
| 索引来源 | 能否直接删 | 正确做法 |
|---|---|---|
| 普通二级索引 | 可以 | DROP INDEX 语句直接删 |
| UNIQUE 约束创建的索引 | MySQL 可删(约束随之消失);PG 不行 | PG 走 ALTER TABLE ... DROP CONSTRAINT |
| 主键索引 | 不能 | 先改主键定义 |
| 外键依赖的索引 | 视情况 | 先删外键,或保留能被外键复用的索引 |
删除唯一索引等于移除数据库层去重:如果应用依赖它拦重复数据,删除后重复值会被静默写入,事后清理代价很高。删前先确认业务是否真的不依赖。
MySQL 8.0 可以先把索引设为 INVISIBLE 做灰度验证;PostgreSQL 没有不可见索引,可观察 pg_stat_user_indexes 的扫描计数,再决定是否删除。