テーブルのインデックスはいつ使用する必要がありますか?
- 何行のインデックスから意味がありますか?
- 一定の行を持つテーブルがある場合、('where'句ではなく)列を編集しただけで、テーブルに約15行しかない場合でもインデックスに意味がありますか?編集:そのような場合、インデックスの読み取りよりもインデックス以外の選択/読み取りの方が効果的ですか?
編集:現在、firebird 2.5を使用していますが、ほとんどの場合、SQLServer2005/2008を使用しています。
テーブルのインデックスはいつ使用する必要がありますか?
編集:現在、firebird 2.5を使用していますが、ほとんどの場合、SQLServer2005/2008を使用しています。
一般に、私のインデックス作成戦略は次のようになります(現在、SQL Serverを排他的に使用しています。必要に応じて独自のデータベースシステムに適合させてください)。
優れたクラスタリングキーを選択します-GUIDでも、VARCHAR(250)
何かでもありません-優れたクラスタリングキーは、狭く、一意で、安定していて、増え続けています-のようなものINT IDENTITY
は完璧です。これをクラスター化された主キーにします->テーブルの最初のインデックスを提供します
別のテーブルへの外部キーとして使用されている列の場合は、インデックスを追加します。単一の列インデックスにすることも、複合インデックスにすることもできます。これは、ケースに最適なものです。外部キー列がそのインデックスの最初の列であることが重要です(複合インデックスを使用している場合)。そうしないと、システムでのJOIN
'sまたは参照整合性のチェックの利点が利用できなくなります。
今のところは以上です。
次に、システムを実行し、観察し、測定し、ベースラインを確立します。アプリは十分に高速ですか?はいの場合->完了です-家に帰って暇な時間を楽しんでください。
そうでない場合:アプリが十分に高速でない理由に関するデータと兆候の収集を開始します。たとえば、SQL ServerのDMVのように、パフォーマンスが最も低いクエリや、欠落しているインデックスDMVについて説明します。それらを分析します。何を改善できるか見てみましょう。一度に1つのインデックスを追加します。観察し、測定し、ベースラインと比較します。
改善がある場合->そのインデックスをそのままにして、この測定値が新しいベースラインになります。あなた(およびあなたのユーザー)がアプリのパフォーマンスに満足するまで(そして家に帰って休暇を楽しむまで)すすぎ、繰り返します。
SQL Serverでの過剰なインデックス作成は、インデックスがない場合よりも悪い場合があります。インデックスが多すぎて始めないでください。適切なクラスター化されたPKと外部キーの非クラスター化インデックスのみを確立し(それだけです)、そのサイクルを観察、測定、最適化、および繰り返します。
これは非常に複雑な議論です。覚えておくべきことがいくつかあります。主に、テーブルにある行数ではなく、それに対して実行するクエリに基づいてインデックスを検討する必要があります。インデックスはクエリの選択にのみ役立ちますが、同時に、テーブルの行を変更するだけでなく、インデックスを変更する必要があるため、挿入、削除、更新のパフォーマンスがわずかに低下します。
あなたはこの問題に慣れていないようです。そのため、実行プランを確認し、すべてのテーブルまたはすべてのインデックスをほとんど読み取るため、すべての「スキャン」操作を排除することをお勧めします。常にシークがあるように見える必要がありますが、それでも、テーブルにあるインデックスの量とバランスを取る必要があります。
SQL Serverを使用している場合は、SQLServerプロファイラーを使用してトレースを実行できます。
編集:
そのような場合、インデックスの読み取りよりも非インデックスの選択/読み取りの方が効果的でしょうか?
はい。ただし、この場合、エンジンはインデックスを使用しないほど賢くなります。
インデックスは、テーブルから行の一部を選択するのに適しています。主キー値によるクエリは、インデックスを最大限に活用することです。最悪のシナリオは、インデックスページと参照データページを読み取る必要があるため、インデックスを介してテーブルからすべての行にアクセスすることです。別の例として、メモリ内での結果セットの並べ替えは、並べ替えられた列のインデックスを介して結果セットを並べ替えるよりも高速な場合があります。また、インデックスはクエリのパフォーマンスを向上させる可能性がありますが、インデックスは書き込みのパフォーマンスを低下させることを忘れないでください。
ある種のトレースユーティリティを使用してパフォーマンスを測定するなど、ベースラインを取得することに言及している人もいます。確立されたパフォーマンスに問題がない場合は、先に進んでください。そうでない場合は、実行プラン、物理データモデル(使用可能なインデックス)を分析し、統計を再計算して、オプティマイザーがより適切な実行プランを選択するのに役立つかどうかを確認します。DBMSが使用可能なRAMを利用できる(許可されている)ことを確認してください。ディスクI/Oなどを最小限に抑えるようにしてください。
Firebird 2.5の場合、新しく追加されたFirebirdTraceAPIは天の恵みです。これで、パフォーマンスカウンター(実行プラン、実行時間、I / O統計など)を使用して、データベースに対して実行された内容をほぼリアルタイムでトレースできるようになりました。また、 UpsceneProductionsのFBTraceManagerと呼ばれるサードパーティ製品により、TraceAPIを楽しく使用できます。
質問の2番目の部分に関しては、テーブルに15行しかない場合、テーブルは非常に小さいため、インデックスがいくつあっても常にスキャンされる可能性が非常に高くなります。
このクエリを使用して、インデックスが必要なテーブルの手がかりを取得します。
-- Missing Indexes for current database by Index Advantage (Query 57) (Missing Indexes)
SELECT DISTINCT CONVERT(decimal(18,2), user_seeks * avg_total_user_cost * (avg_user_impact * 0.01)) AS [index_advantage],
migs.last_user_seek, mid.[statement] AS [Database.Schema.Table],
mid.equality_columns, mid.inequality_columns, mid.included_columns,
migs.unique_compiles, migs.user_seeks, migs.avg_total_user_cost, migs.avg_user_impact,
OBJECT_NAME(mid.[object_id]) AS [Table Name], p.rows AS [Table Rows]
FROM sys.dm_db_missing_index_group_stats AS migs WITH (NOLOCK)
INNER JOIN sys.dm_db_missing_index_groups AS mig WITH (NOLOCK)
ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details AS mid WITH (NOLOCK)
ON mig.index_handle = mid.index_handle
INNER JOIN sys.partitions AS p WITH (NOLOCK)
ON p.[object_id] = mid.[object_id]
WHERE mid.database_id = DB_ID()
ORDER BY index_advantage DESC OPTION (RECOMPILE);
これはあなたに北を与えるだけであることに注意してください、あなたはまだ上で答えられたものを考慮に入れる必要があります。