この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:atom
更新日時:2026-06-12 15:30:23

タイトル: インデックスの削除
SEOタイトル: SQLでインデックスを削除する方法|DROP INDEXのRDBMS別の書き方

SQLでインデックスを削除するには、DROP INDEX文を使う。MySQLではDROP INDEX インデックス名 ON テーブル名;またはALTER TABLE テーブル名 DROP INDEX インデックス名;、PostgreSQL・OracleではDROP INDEX インデックス名;、SQL ServerではDROP INDEX テーブル名.インデックス名;のように記述するのが基本だが、対象とするRDBMSによって構文が異なる点に注意したい。

この記事の要点
  • インデックスの削除にはDROP INDEX文を使用する。
  • テーブル名の指定方法(ON テーブル名が必要か等)はRDBMSによって異なる。
  • MySQLではALTER TABLE ... DROP INDEXという書き方も使える。
  • 削除前にSHOW INDEX FROM テーブル名などでインデックスの存在・名前を確認すると安全。
  • 主キー(PRIMARY KEY)や一意制約(UNIQUE)は制約として扱われ、別の操作で削除する必要がある場合が多い。
  • 不要・重複したインデックスや、書き込み性能を劣化させているインデックスが削除の主な対象となる。

 

DROP INDEX文の基本構文

インデックスを削除する基本的なSQL文がDROP INDEXである。どのインデックスを削除するかを名前で指定し、RDBMSによってはどのテーブルに属するインデックスかも併せて指定する。代表的なRDBMSごとの書き方を順に見ていく。

MySQL / MariaDBの場合

MySQLおよびMariaDBでは、削除対象のインデックスがどのテーブルに属するかをON テーブル名で指定する。

DROP INDEX idx_user_email ON users;

 

また、ALTER TABLE文の一部としてインデックスを削除することもできる。こちらの書き方は、同じALTER TABLE文の中で列の追加や変更とまとめて記述できる点が便利である。

ALTER TABLE users DROP INDEX idx_user_email;

 

どちらの構文も結果は同じで、idx_user_emailというインデックスがusersテーブルから削除される。なお、MySQLではINDEXの代わりにKEYと書くこともできる。

PostgreSQLの場合

PostgreSQLでは、インデックス名がスキーマ内で一意であるため、テーブル名を指定せずインデックス名だけで削除する。

DROP INDEX idx_user_email;

 

存在しないインデックスを指定するとエラーになるため、存在する場合のみ削除したいときはIF EXISTSを付ける。また、テーブルへの書き込みをブロックせずに削除したい場合はCONCURRENTLYを指定できる(この場合トランザクションブロック内では実行できない)。

DROP INDEX IF EXISTS idx_user_email;

DROP INDEX CONCURRENTLY idx_user_email;

 

Oracle Databaseの場合

OracleもPostgreSQLと同様に、インデックス名のみを指定して削除する。

DROP INDEX idx_user_email;

 

SQL Serverの場合

SQL Serverでは、どのテーブルのインデックスかをテーブル名.インデックス名の形式で指定する。

DROP INDEX users.idx_user_email;

 

新しいバージョンのSQL Serverでは、次のようにON句を使う構文やIF EXISTSも利用できる。

DROP INDEX idx_user_email ON users;

DROP INDEX IF EXISTS idx_user_email ON users;

 

RDBMS別の構文の違い

同じ「インデックスの削除」でも、テーブル名の指定方法やオプションはRDBMSごとに差がある。主要なRDBMSの書き方を比較すると次のようになる。

RDBMS 基本構文 テーブル名の指定 主な補足
MySQL / MariaDB DROP INDEX idx ON テーブル; ON テーブル名で指定(必須) ALTER TABLE ... DROP INDEXも可
PostgreSQL DROP INDEX idx; 不要(名前のみ) IF EXISTS / CONCURRENTLYが使える
Oracle DROP INDEX idx; 不要(名前のみ) 制約由来のインデックスは制約側で削除
SQL Server DROP INDEX テーブル.idx; テーブル名.またはON テーブル名 新しい版ではON句・IF EXISTSに対応

 

このように、MySQLとSQL Serverはテーブル名の指定が必要で、PostgreSQLとOracleはインデックス名のみで削除できる、という違いがある。バージョンによって対応する構文や使えるオプションが異なる場合があるため、利用するRDBMSの公式ドキュメントも確認すると確実である。

削除前にインデックスを確認する

削除を実行する前に、対象のテーブルにどのようなインデックスが存在し、それぞれの名前が何かを確認しておくとよい。インデックス名を間違えるとエラーになったり、意図しないインデックスを消してしまったりするおそれがあるためである。インデックスの一覧を確認する方法もRDBMSによって異なる。

-- MySQL / MariaDB

SHOW INDEX FROM users;

 

-- PostgreSQL(psql のメタコマンド、または pg_indexes ビュー)

\d users

SELECT indexname FROM pg_indexes WHERE tablename = 'users';

 

-- Oracle

SELECT index_name FROM user_indexes WHERE table_name = 'USERS';

 

-- SQL Server

SELECT name FROM sys.indexes WHERE object_id = OBJECT_ID('users');

 

これらでインデックス名や対象列を確認したうえで、DROP INDEXを実行すると安全である。

いつインデックスを削除するか

インデックスは検索(SELECT)を高速化するために作成するものだが、すべてのインデックスが常に有益とは限らない。次のようなケースでは、インデックスの削除を検討する価値がある。

  • 使われていない不要なインデックス:作成したものの、実際のクエリでは利用されていないインデックス。残しておくと無駄にディスク領域を消費し、更新時のオーバーヘッドだけが残る。
  • 重複したインデックス:同じ列、または先頭列が同一の複合インデックスが重複して存在するケース。一方は冗長になりやすく、整理の対象となる。
  • 書き込み性能を劣化させているインデックス:インデックスはINSERT / UPDATE / DELETEのたびに更新されるため、数が多いと書き込み性能が低下する。検索の恩恵より更新のコストが上回るインデックスは削除を検討する。

逆に、新しくインデックスを作成する方法については関連記事のインデックスの作成を参照してほしい。削除と作成はセットで理解しておくと、インデックスの設計・見直しがしやすくなる。

削除時の落とし穴

注意すべきポイント
  • 主キー・一意制約は制約として扱われる:PRIMARY KEYやUNIQUE制約に紐づくインデックスは、単純なDROP INDEXでは削除できない、あるいは制約側の操作が必要になることが多い。MySQLではALTER TABLE テーブル名 DROP PRIMARY KEY;、PostgreSQLやOracle、SQL ServerではALTER TABLE テーブル名 DROP CONSTRAINT 制約名;のように、制約として削除する。
  • 削除中のロックに注意:インデックスの削除はテーブルに対してロックを取得する場合があり、その間は他の処理が待たされることがある。大規模なテーブルや稼働中の本番環境では、影響の少ない時間帯に実施するか、PostgreSQLのCONCURRENTLYのようにロックを抑える仕組みを利用するとよい。
  • 消すと検索が遅くなることがある:そのインデックスを利用していたクエリは、削除後にフルスキャンになり大幅に遅くなる可能性がある。本当に不要かを実行計画(EXPLAINなど)で確認してから削除するのが望ましい。

 

よくある質問(FAQ)

Q. 存在しないインデックスを削除しようとするとどうなりますか?

多くのRDBMSでは、指定したインデックスが存在しない場合にエラーとなる。エラーを避けて「存在する場合のみ削除」したいときは、PostgreSQLやSQL Server(新しいバージョン)、MySQLなどで利用できるIF EXISTSを付ける。例えばPostgreSQLではDROP INDEX IF EXISTS idx_user_email;のように記述する。

Q. インデックスを削除するとテーブルのデータも消えますか?

消えない。DROP INDEXはインデックス(検索を高速化するための補助的なデータ構造)だけを削除するものであり、テーブル本体の行データには影響しない。削除後はそのインデックスが効いていた検索が遅くなる可能性はあるが、データそのものはそのまま残る。

Q. 削除したインデックスを元に戻すにはどうすればよいですか?

削除を取り消す専用の操作はないため、再度CREATE INDEXで同じ定義のインデックスを作り直す。元の列構成やインデックス名を控えておけば、同じインデックスを再作成できる。具体的な作成方法はインデックスの作成を参照してほしい。