はじめに
データベースを効率的に運用するために欠かせない概念の一つが「カーディナリティ」です。SQLにおけるカーディナリティは、データベースのパフォーマンス最適化やインデックス設計において重要な役割を果たします。
この記事では、SQLカーディナリティの基本概念から実践的な活用方法まで、初心者にも分かりやすく解説します。
カーディナリティとは何か
カーディナリティ(Cardinality)とは、データベースにおいて「データの種類の多さ」や「ユニークな値の数」を表す概念です。
基本的な定義
カーディナリティは以下の2つの文脈で使用されます:
1. 統計的カーディナリティ
- テーブルの特定の列に含まれる異なる値の数
- 例:性別列の場合、「男性」「女性」の2つの値しかないため、カーディナリティは2
2. 関係的カーディナリティ
- テーブル間の関係性を表す概念
- 1対1、1対多、多対多の関係を定義
カーディナリティの種類
高カーディナリティ(High Cardinality)
列に含まれる異なる値の数が多い状態を指します。
特徴:
- ユニークな値が多数存在
- 重複する値が少ない
- 選択性が高い
例:
- 社員ID(全て異なる値)
- メールアドレス
- 商品コード
低カーディナリティ(Low Cardinality)
列に含まれる異なる値の数が少ない状態を指します。
特徴:
- 限られた種類の値のみ存在
- 同じ値が頻繁に重複
- 選択性が低い
例:
- 性別(男性、女性)
- 都道府県名
- ステータス(有効、無効)
カーディナリティがパフォーマンスに与える影響
インデックスの効果
高カーディナリティの列
sql-- 社員IDでの検索(高カーディナリティ)
SELECT * FROM employees WHERE employee_id = 'EMP001';
-- インデックスが非常に効果的
低カーディナリティの列
sql-- 性別での検索(低カーディナリティ)
SELECT * FROM employees WHERE gender = '男性';
-- インデックスの効果が限定的
クエリオプティマイザーの判断
データベースのクエリオプティマイザーは、カーディナリティ情報を使用して最適な実行計画を決定します。
高カーディナリティの場合:
- インデックススキャンを選択しやすい
- 絞り込み効果が高い
- 効率的な検索が可能
低カーディナリティの場合:
- フルテーブルスキャンを選択する場合がある
- インデックスを使用してもあまり効果がない
- 他の条件と組み合わせた複合インデックスが有効
実践的な活用方法
1. インデックス設計での考慮点
効果的なインデックス設計:
sql-- 高カーディナリティ列に単一インデックス
CREATE INDEX idx_employee_id ON employees(employee_id);
-- 低カーディナリティ列は複合インデックスで
CREATE INDEX idx_dept_status ON employees(department, status);
2. 統計情報の活用
PostgreSQLでの統計情報確認:
sql-- 列の統計情報を確認
SELECT
attname,
n_distinct,
correlation
FROM pg_stats
WHERE tablename = 'employees';
MySQLでの統計情報確認:
sql-- インデックスの統計情報を確認
SHOW INDEX FROM employees;
3. クエリ最適化の戦略
高カーディナリティ列を活用した絞り込み:
sql-- 効率的な絞り込み順序
SELECT * FROM orders
WHERE order_id = 'ORD001' -- 高カーディナリティで先に絞り込み
AND status = 'shipped'; -- 低カーディナリティは後
カーディナリティ推定の重要性
統計情報の更新
データベースの統計情報を定期的に更新することで、正確なカーディナリティ推定が可能になります。
PostgreSQL:
sql-- 統計情報の更新
ANALYZE table_name;
MySQL:
sql-- 統計情報の更新
ANALYZE TABLE table_name;
SQL Server:
sql-- 統計情報の更新
UPDATE STATISTICS table_name;
推定精度の向上
統計情報のサンプリング調整:
sql-- PostgreSQLでサンプリング率を調整
ALTER TABLE employees ALTER COLUMN department SET STATISTICS 1000;
設計時の注意点
1. 将来的な変化を考慮
現在は低カーディナリティでも、将来的に高カーディナリティになる可能性がある列について考慮が必要です。
2. 複合インデックスの順序
複合インデックスでは、カーディナリティの高い列を先頭に配置することが一般的です。
sql-- 推奨:高カーディナリティを先頭に
CREATE INDEX idx_user_search ON users(user_id, department, status);
-- 非推奨:低カーディナリティが先頭
CREATE INDEX idx_user_search_bad ON users(status, department, user_id);
3. データ分布の偏り
カーディナリティが高くても、データの分布に偏りがある場合は注意が必要です。
まとめ
SQLのカーディナリティは、データベースの設計とパフォーマンス最適化において重要な概念です。
重要なポイント:
- 高カーディナリティ:異なる値が多く、インデックスが効果的
- 低カーディナリティ:異なる値が少なく、複合インデックスが有効
- 統計情報の維持:正確な推定のために定期的な更新が必要
- 設計時の考慮:将来的な変化やデータ分布も考慮した設計が重要
適切なカーディナリティの理解と活用により、効率的なデータベース運用が実現できます。継続的な監視と最適化により、常に最高のパフォーマンスを維持していきましょう。