update
文では、インデックスの順序を維持するために、
変更されたインデックスを移動させなければなりません。そのために、データベースは古いエントリを削除し、新しいエントリを新しい場所に作ります。
応答時間は通常、対応するdelete
文とinsert
文を同時に実行したのとほぼ同じになります。
update
のパフォーマンスは、insert
やdelete
と同じくテーブルに作られたインデックスの数に依存します。唯一の違いは、
update
文は必要な列しか選択しない場合が多いので、
全列を更新しなくても良い事です。従って、update
文では
テーブルの全てのインデックスではなく、更新される列が含まれるインデックスだけを更新すれば良いのです。
図8.3は、2つのupdate
文の応答時間を表したものです。
1つは全列を更新するため全インデックスに影響がある場合、もう1つは1列しか変更しないのでインデックス1つにしか影響がない場合です。
図8.3インデックスと列数による更新のパフォーマンス変化
全列を更新するupdate
文では、前の節で見たのと同じように、インデックスが増えるごとに応答時間が増えています。
1つのインデックスにしか影響がないupdate
文の
応答時間は、他のインデックスに影響を与えないため、インデックス数が増えてもほとんど変わりません。
update
のパフォーマンスを最適化するには、
変更する列のみを更新するよう注意を払う必要があります。手動でupdate
文を実行するなら、そんなことは当たり前に
思えるかもしれません。しかし、ORMツールは毎回全ての列を更新するupdate
文を生成してしまう事があります。例えばHibernateは、ダイナミックアップデート
モードが無効な時は、常に全列を更新してしまいます。
バージョン4.0からは、デフォルトでこの機能は有効になりました。
ORMツールを使う場合、生成されたSQLを確認するために、開発環境では時々クエリのロギング機能を有効にしてみるのが良いでしょう。 「SQLのロギングを有効にする」では 広く使われているORMツールでSQLのロギングを有効にする方法を簡単に説明しています。
考えてみよう
insert
やdelete
が、テーブルに作られた全てのインデックスに影響を与えない場面は
あり得るでしょうか?