Skip to content

sql-drop-index

尽管索引对于查询性能至关重要,但也有充分的理由删除它们。你可能会删除索引,如果:

  • 它不再被任何查询使用。
  • 它的选择性较低,几乎没有或根本没有性能提升。
  • 在数据插入、更新和删除期间维护索引的性能成本超过了其读取性能带来的好处。
  • 你计划用一个更有效的复合索引来替换它。

注意:删除索引可能会严重降低依赖它的查询的性能。在生产环境中删除索引之前,请务必在开发或测试环境中分析其影响。

删除索引的标准命令是 DROP INDEX。确切的语法在不同数据库系统之间可能略有不同。

在 PostgreSQL 和 SQL Server 中,你通常需要指定索引名称及其所属的表。

/* PostgreSQL */
DROP INDEX index_name;
/* SQL Server */
DROP INDEX index_name ON table_name;

在 MySQL 中,语法要求指定表名。

DROP INDEX index_name ON table_name;

首先,让我们创建一个表并在 email 列上创建一个索引。

CREATE TABLE Users (
user_id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100)
);
CREATE INDEX idx_users_email ON Users(email);

现在,让我们使用 MySQL/SQL Server 语法删除该索引。

DROP INDEX idx_users_email ON Users;

在删除索引之前,你需要知道它的名称。列出索引的方法因数据库系统而异。

  • PostgreSQL:在 psql 客户端中使用 \d table_name 命令。
  • MySQL:使用 SHOW INDEX FROM table_name; 命令。
  • SQL Server:使用 EXEC sp_helpindex 'table_name'; 存储过程。

如果你尝试删除一个不存在的索引,你的 SQL 脚本将失败。为了防止这种情况,许多数据库支持 IF EXISTS 子句,该子句只在找到索引时才执行命令,否则不执行任何操作。

/* PostgreSQL 和 SQL Server */
DROP INDEX IF EXISTS idx_users_email ON Users;

这使得数据库迁移脚本更健壮、可重复运行。

从约束中删除索引(PRIMARY KEY 或 UNIQUE)

Section titled “从约束中删除索引(PRIMARY KEY 或 UNIQUE)”

这是一个关键点:你不能使用 DROP INDEX 来删除由 PRIMARY KEY 或 UNIQUE 约束自动创建的索引。

要删除此类索引,你必须使用 ALTER TABLE 删除约束本身。

让我们向 Users 表添加一个唯一约束,这也会创建一个唯一索引。

ALTER TABLE Users
ADD CONSTRAINT uq_users_username UNIQUE(username);

以下命令将失败:

-- 这将产生一个错误!
DROP INDEX uq_users_username ON Users;

删除索引和唯一性保证的正确方法是删除约束:

-- 这是正确的方法。
ALTER TABLE Users
DROP CONSTRAINT uq_users_username;
  • 命名你的索引和约束:始终为你的索引(例如,idx_table_column)和约束(例如,pk_table、uq_table_column)提供明确的名称。这使得删除它们变得明确且容易。
  • 删除前分析:在删除索引之前,使用 EXPLAIN 或 EXPLAIN ANALYZE 等工具确认重要的查询没有使用该索引。
  • 使用 IF EXISTS:在你的脚本中,使用 IF EXISTS 来避免错误并使其幂等(可重复运行而不会出现问题)。
  • 监控性能:在生产环境中删除索引后,监控你的应用程序和数据库性能,以确保没有负面影响。