CRM データベースチューニング - インデックスはつけるべき? パート 2
みなさん、こんにちは。
今週は、東京でまた雪が降りましたね。寒すぎて、桜がどうなるか既に心配です。今回は、前回に引き続きインデックスの
パート 2 ということで、インデックスの良い面と悪い面を紹介したいと思います。では早速。
インデックスの良い面
インデックスは、特定のレコードを検索するために活用できます。よって select 処理はもちろん、特定の行を更新する
update 処理や、特定の行を削除する delete でもその効果を発揮します。また、複数のテーブルを結合する Join 処理
などでも、列を特定する必要があるため、効果が期待できます。
インデックスの悪い面
その一方でデータが書き換わる処理、つまり insert、update、delete が行われた場合には、関連するインデックスが
更新される必要があります。
前回に引き続き、以下のテーブルを考えて見ます。(携帯番号列を追加しています。)
<メンバーテーブル>
ID | 名前 | 電話番号 | 携帯番号 |
1 | 中村 憲一郎 | 03-1234-xxxx | 090-1234-xxxx |
2 | 斎藤 さち江 | 03-5555-xxxx | 090-5555-xxxx |
3 | 矢野 時枝 | 03-3333-xxxx | 090-3333-xxxx |
また非クラスタ化インデックスが、前回同様、電話番号にあるとします。
ID | 電話番号 |
1 | 03-1234-xxxx |
3 | 03-3333-xxxx |
2 | 03-5555-xxxx |
さてこの場合、以下のクエリを実行すると仮定しましょう。
insert into メンバーテーブル (名前、電話番号、携帯番号) values (‘河越 弘典’, ‘03-6666-xxxx’, ‘090-6666-xxxx’)
この場合、当然メンバーテーブルは新しい行が追加されるため、SQL Server によってメンテナンスされます。また同時に
電話番号列に作成した、非クラスタ化インデックスもメンテナンスされることになります。また電話番号列を更新するような
update が処理された場合も同様です。
では、次のクエリではどうでしょうか。
update メンバーテーブル set 携帯番号 = ‘090-2345-xxxx’ where 名前 = ‘中村 憲一郎’
この場合、携帯番号の更新のため、電話番号列には更新がなく、非クラスタ化インデックスはメンテナンスされません。
このように状況に応じて内容は変わるものの、非クラスタ化インデックスを持つ場合は、実際のテーブル以外にインデックス
もメンテナンスされる場合がありますし、クラスタ化インデックスがあるテーブルでは、insert されるたびに、順番を確認して
データを保存することとなり、パフォーマンスに影響が出ます。
では、どうすればいいの?
対処の方針は、そのシステムによって変わります。一般的にレポートや分析サービスのように、更新が少なく読み取りが
多いシステムの場合には、インデックスが効果を発揮します。その一方で、トランザクションが多いシステムの場合には、
インデックスがあることで処理が低下する恐れもあります。そのため、必要最小限のインデックスを作成を心がけてください。
他の注意点は?
インデックスを作成した場合、並び替えなどの処理はSQL Server が自動で行いますが、インデックスのデータに発生した
フラグメントは解消してくれません。そのため、インデックスのデフラグメントが必要となります。デフラグメントの方法は
いくつかありますので、以下の URL を参考にしてください。
効果的なデータベース メンテナンスのヒント
https://technet.microsoft.com/ja-jp/magazine/2008.08.database.aspx#id0230032
さて次回は、非クラスタ化インデックスに含めるべき列や、その手法に関して紹介したいと思います。お楽しみに。
- Dynamics CRM サポート 中村 憲一郎