第3部:AIとバックエンド高度化 Step 10 / 36

データベース最適化

N+1問題、インデックス設計、クエリ最適化をAIに分析・改善させて、データベースパフォーマンスを向上させます。

N+1問題の検出と解決

AIに分析を依頼

以下のコードにN+1問題がありますか?
問題があれば、修正方法を示してください。

```python
def get_posts_with_authors():
    posts = db.query(Post).all()
    result = []
    for post in posts:
        result.append({
            "title": post.title,
            "author_name": post.author.name  # ← ここ
        })
    return result
```

問題のあるコード

# 1回 + N回のクエリが発生
posts = db.query(Post).all()  # 1回
for post in posts:
    post.author.name  # N回(投稿数分)

改善後

# joinedloadで1回のクエリに
from sqlalchemy.orm import joinedload

posts = db.query(Post).options(
    joinedload(Post.author)
).all()

インデックス設計

AIへの指示

以下のクエリパターンに対して、適切なインデックスを提案してください。

【よく実行されるクエリ】
1. WHERE user_id = ? AND status = 'active'
2. WHERE created_at > ? ORDER BY created_at DESC
3. WHERE title LIKE '%keyword%'

【テーブル】tasks(id, user_id, title, status, created_at)

推奨インデックス

-- 複合インデックス(クエリ1用)
CREATE INDEX idx_tasks_user_status ON tasks(user_id, status);

-- 単一インデックス(クエリ2用)
CREATE INDEX idx_tasks_created_at ON tasks(created_at DESC);

-- 全文検索用(クエリ3用、LIKEの前方一致以外は効かない)
-- MySQLの場合: FULLTEXT INDEX
CREATE FULLTEXT INDEX idx_tasks_title ON tasks(title);

スロークエリの分析

EXPLAINの結果を分析させる

以下のEXPLAIN結果を分析して、改善案を教えてください。

EXPLAIN SELECT * FROM orders
WHERE user_id = 123 AND created_at > '2024-01-01';

| type | key  | rows   | Extra       |
|------|------|--------|-------------|
| ALL  | NULL | 500000 | Using where |

まとめ

  • N+1問題 - joinedload/selectinloadで解決
  • インデックス - クエリパターンに合わせて設計
  • EXPLAIN - 実行計画を確認して最適化
キャッシュ設計と実装 次へ:API設計の高度化