Skip to content

インデックス設計の推奨事項

概要

適切なインデックス設計は、データベースのパフォーマンスを大幅に向上させる最も重要な要素の一つです。TDSQL Boundless の分散環境では、従来の MySQL でのインデックス設計に加えて、分散トランザクションやデータ分散を考慮したインデックス戦略が必要です。

インデックスの基本原則

1. 選択性の高いカラムにインデックスを作成する

選択性(Selectivity)とは、カラムのユニーク値の数をテーブルの総行数で割った値です。選択性が高いほど、インデックスの効果が大きくなります。

sql
-- 選択性の確認
SELECT 
    COUNT(DISTINCT column_name) / COUNT(*) AS selectivity
FROM table_name;
  • 選択性が 0.1 以上: インデックスの効果が見込める
  • 選択性が 0.01 未満: インデックスの効果が限定的

2. クエリパターンに基づいてインデックスを設計する

インデックスは、実際のクエリパターンに基づいて設計する必要があります。使用されないインデックスは、書き込み性能の低下とストレージの無駄につながります。

sql
-- 使用されていないインデックスの確認
SELECT 
    object_schema,
    object_name,
    index_name
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE index_name IS NOT NULL
AND count_star = 0
AND object_schema NOT IN ('mysql', 'performance_schema');

3. 複合インデックスの列順序を最適化する

複合インデックスでは、以下の順序でカラムを配置します。

  1. 等価条件(=)で使用されるカラム
  2. 範囲条件(>, <, BETWEEN)で使用されるカラム
  3. ORDER BY / GROUP BY で使用されるカラム
sql
-- クエリ例
SELECT * FROM orders 
WHERE status = 'shipped' 
AND order_date > '2026-01-01' 
ORDER BY total_amount;

-- 最適なインデックス
CREATE INDEX idx_orders_composite 
ON orders(status, order_date, total_amount);

カバリングインデックスの活用

カバリングインデックスとは

クエリに必要なすべてのカラムがインデックスに含まれている場合、テーブルへのアクセスが不要になります。これをカバリングインデックスと呼びます。

sql
-- カバリングインデックスの例
CREATE INDEX idx_covering ON orders(user_id, order_date, total_amount);

-- このクエリはインデックスのみで完結する(Using index)
SELECT user_id, order_date, total_amount 
FROM orders 
WHERE user_id = 1001;

メリット

  • テーブルへのランダムI/Oが不要になる
  • 特に分散環境では、リモートノードへのアクセス回数を削減できる
  • EXPLAIN の Extra に「Using index」が表示される

注意点

  • カバリングインデックスのサイズが大きくなりすぎないよう注意する
  • 書き込みが多いテーブルでは、インデックスのメンテナンスコストを考慮する

分散環境でのインデックス戦略

シャードキーとインデックスの関係

TDSQL Boundless では、シャードキーがデータの配置先を決定します。インデックス設計においては、シャードキーとの関係を考慮する必要があります。

sql
-- シャードキーを含むインデックス(効率的)
-- シャードキー: user_id
CREATE INDEX idx_user_orders ON orders(user_id, order_date);

-- シャードキーを含まないインデックス(クロスノードスキャンの可能性)
CREATE INDEX idx_order_date ON orders(order_date);

グローバルインデックスとローカルインデックス

  • ローカルインデックス — 各ノードのデータに対してのみ機能する。シャードキーを含むクエリで効率的
  • グローバルインデックス — クラスタ全体のデータに対して機能する。シャードキーを含まないクエリで有用だが、オーバーヘッドが大きい

分散トランザクションを考慮したインデックス

分散環境では、インデックスの更新がトランザクションの一部として処理されます。以下の点を考慮してください。

  1. インデックス数を最小限に抑える — 各インデックスの更新が分散トランザクションのコストを増加させる
  2. シャードキーを含むインデックスを優先する — シングルノードでの処理に絞り込める
  3. ユニークインデックスの影響 — 分散環境でのユニーク制約は、クロスノードチェックが必要な場合がある

インデックスのアンチパターン

避けるべきパターン

  1. 全カラムへのインデックス作成
sql
-- 非推奨:すべてのカラムに個別インデックスを作成
CREATE INDEX idx_col1 ON table1(col1);
CREATE INDEX idx_col2 ON table1(col2);
CREATE INDEX idx_col3 ON table1(col3);
-- ... すべてのカラムに対して

-- 推奨:実際のクエリパターンに基づいた複合インデックス
CREATE INDEX idx_composite ON table1(col1, col2);
  1. 低選択性カラムへのインデックス
sql
-- 非推奨:性別など値の種類が少ないカラム
CREATE INDEX idx_gender ON users(gender);

-- 推奨:選択性の高いカラムと組み合わせる
CREATE INDEX idx_gender_name ON users(gender, last_name);
  1. 重複インデックス
sql
-- 重複するインデックス
CREATE INDEX idx_a ON table1(col_a);
CREATE INDEX idx_ab ON table1(col_a, col_b);
-- idx_a は idx_ab で代替可能なため不要

インデックスの管理

定期的な見直し

sql
-- インデックスの使用状況の確認
SELECT 
    object_schema,
    object_name,
    index_name,
    count_read,
    count_write
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE object_schema = 'your_database'
ORDER BY count_read DESC;

-- インデックスサイズの確認
SELECT 
    table_name,
    index_name,
    ROUND(stat_value * @@innodb_page_size / 1024 / 1024, 2) AS size_mb
FROM mysql.innodb_index_stats
WHERE database_name = 'your_database'
AND stat_name = 'size';

不要なインデックスの削除

使用されていないインデックスは、書き込み性能に悪影響を与えます。定期的に見直し、不要なインデックスを削除してください。

まとめ

インデックス設計は、TDSQL Boundless のパフォーマンス最適化において中核的な要素です。分散環境では、シャードキーとの関係やクロスノードアクセスの影響を考慮した設計が求められます。実際のクエリパターンに基づいた適切なインデックス設計を行い、定期的に見直しを実施してください。

詳細な仕様については、元ドキュメントをご参照ください。

Tencent Cloud プロダクトドキュメント