2.

MySQL インデックス一覧の確認(SHOW INDEX / information_schema 完全ガイド)

編集
この記事の要点
  • 基本: SHOW INDEX FROM テーブル名; でテーブルに紐づく全インデックスを一覧表示
  • 詳細情報: information_schema.STATISTICS から SQL で集計・抽出可能
  • 主要列: Key_name (インデックス名) / Column_name (対象列) / Non_unique (0=ユニーク) / Cardinality (推定行数)
  • DDL ごと見る: SHOW CREATE TABLE テーブル名; — インデックス含む完全な定義
  • 使われ方を見る: EXPLAINEXPLAIN ANALYZE実行計画に出るインデックス名を確認

MySQL でインデックス一覧を確認する

MySQL でテーブルに作成されたインデックスを確認する方法は複数あります。用途に応じて使い分けるのがコツです。

用途コマンド
とにかく一覧を見たいSHOW INDEX FROM テーブル名;
DDL を取得したいSHOW CREATE TABLE テーブル名;
SQL でフィルタ / JOINSELECT ... FROM information_schema.STATISTICS
未使用インデックスを探すsys.schema_unused_indexes
クエリでの使用を確認EXPLAIN SELECT ...

1. SHOW INDEX — 標準コマンド

-- 基本構文
SHOW INDEX FROM テーブル名;

-- 別 DB を指定
SHOW INDEX FROM mydb.users;

-- 別名 (どれも同じ動き)
SHOW INDEXES FROM users;
SHOW KEYS    FROM users;

出力例:

+--------+------------+---------------+--------------+-------------+-----------+-------------+
| Table  | Non_unique | Key_name      | Seq_in_index | Column_name | Collation | Cardinality |
+--------+------------+---------------+--------------+-------------+-----------+-------------+
| users  |          0 | PRIMARY       |            1 | id          | A         |       10000 |
| users  |          0 | uniq_email    |            1 | email       | A         |       10000 |
| users  |          1 | idx_name_age  |            1 | name        | A         |        9500 |
| users  |          1 | idx_name_age  |            2 | age         | A         |       10000 |
+--------+------------+---------------+--------------+-------------+-----------+-------------+

主要カラムの意味

カラム意味
Key_nameインデックス名。PRIMARY が主キー
Non_unique0 = UNIQUE / 1 = 重複可
Seq_in_index複合インデックスの何番目のカラムか
Column_name対象カラム名
Collation並び順(A=ASC / D=DESC / NULL=未ソート)
Cardinality推定ユニーク値数。低いと選択性が悪い
Sub_partプレフィックスインデックスのプレフィックス長
Index_typeBTREE / HASH / FULLTEXT / SPATIAL
VisibleYES / NO(8.0+)。NO は実行計画で無視される

2. SHOW CREATE TABLE — DDL 全体

カラム定義 + インデックス + 外部キーをまとめて確認したいときに。

SHOW CREATE TABLE users \G
*************************** 1. row ***************************
       Table: users
Create Table: CREATE TABLE `users` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `name` varchar(50) NOT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_email` (`email`),
  KEY `idx_name_age` (`name`, `age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

3. information_schema.STATISTICS

SQL でフィルタしたいときは information_schema.STATISTICS を SELECT します。

-- 特定テーブルのインデックス一覧
SELECT
    INDEX_NAME,
    COLUMN_NAME,
    SEQ_IN_INDEX,
    NON_UNIQUE,
    INDEX_TYPE,
    CARDINALITY
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'mydb'
  AND TABLE_NAME   = 'users'
ORDER BY INDEX_NAME, SEQ_IN_INDEX;

-- DB 全体でユニーク制約だけ抽出
SELECT TABLE_NAME, INDEX_NAME, GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS cols
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'mydb' AND NON_UNIQUE = 0
GROUP BY TABLE_NAME, INDEX_NAME;

4. 未使用インデックスを探す (MySQL 5.7+)

本番環境で「使われていないインデックス」を探すのは sys スキーマが便利。Performance Schema が有効なら自動で集計されます。

-- 一度も使われていないインデックス
SELECT * FROM sys.schema_unused_indexes;

-- インデックス使用統計
SELECT * FROM sys.schema_index_statistics
WHERE table_schema = 'mydb'
ORDER BY rows_selected DESC;

5. EXPLAIN でクエリ実行計画を確認

「このクエリでこのインデックスが使われているか?」を見るには EXPLAIN

EXPLAIN SELECT * FROM users WHERE name = 'tarou' AND age = 30;
+----+-------------+-------+------+-------------------+--------------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys     | key          | key_len | ref   | rows | Extra                 |
+----+-------------+-------+------+-------------------+--------------+---------+-------+------+-----------------------+
|  1 | SIMPLE      | users | ref  | idx_name_age      | idx_name_age | 207     | const |   1  | Using index condition |
+----+-------------+-------+------+-------------------+--------------+---------+-------+------+-----------------------+

key 列がそのクエリで実際に使われたインデックス名。NULL なら全表スキャン。

FAQ

Q: PRIMARY KEY と UNIQUE の見分け方
A: SHOW INDEXKey_name = 'PRIMARY' が主キー。それ以外で Non_unique = 0 が UNIQUE インデックス。

Q: インデックスのサイズを知りたい
A: information_schema.TABLESINDEX_LENGTH 列でテーブルごとの合計サイズが取れる。個別は mysql.innodb_index_stats

Q: Cardinality が NULL や極端に低い
A: 統計が古い。ANALYZE TABLE テーブル名; で更新できる。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 実行計画の出力
  2. テーブルに紐づくインデックスを確認する方法

最近更新/作成されたページ