本日はSQLコーディングに関して。
ここら辺は実際にプログラムを書く際に重要になってくるネタ。
Contents
バインド変数
SQLでプリペアードステートメントを書くのではなく、生のSQLをそのまま書いてしまう手法。
デメリット
- 実行計画をSQLを書くたびに作成することになるので、負荷が高くなり、性能が落ちる
- SQLインジェクション
対策
- バインドするようにプログラムを書き換える
- 特に発行頻度が高い(ループ内部など)と思われるところを優先的に書きなおす
- 例外的なケースとしてはフラグ系のところはそれほど影響がない(決め打ちのデータならば処理量は増えないため)
直積により組み合わせが爆発する
SQLの自己結合や外部結合は基本的にはレコードをすべて掛け算するような作りになっている。そのため、結合条件を忘れ、組み合わせが増えすぎてしまうこともある。
結合はループをしていると考える。
デメリット
- データ量が増えるにつれ、負荷が高くなり、影響度が多くなる
- 特定のSQL(組み合わせが多すぎる)のみCPU負荷が大きくなる
対策
- 結合条件の見直し(結合は基本的にはループと同列に考える。そのためまずはカーディナリティが大きいものから結合したほうが早くなる)
- 実行計画要チェック
データ量の爆発(インデックスが不適切)
インデックスが不適切に張られていた場合、フルスキャンを行わなくてはならなくなり、スピードが落ちる。特にデータ量が増えたときに影響が顕著。実行計画への理解も必要
デメリット
- サービスを開始してしばらくしてから特に影響が大きくなる
- CPU使用率が100%になっている
- 単純に遅い
対策
- 性能テストを早い段階でしておく(大量データでのテストが必要)
- 実行計画を確認し、SQLが適切かどうかの確認を行う
インデックスの貼りすぎ
インデックスを張りすぎると、更新系の作業で非常に時間がかかることになる
デメリット
- 検索は早いが、データ更新作業で時間がかかることになる
対策
- インデックス数に関する制限数を行う
- 正規化されていない列数が多い
- 大量更新系のテストをしていない
- 検索が中心になるテーブルの場合は、インデックスを張ることを優先してOKにする