回答:
最初からインデックス作成を開始する必要がありますか、それともパフォーマンスの問題が発生したときですか?
インデックス作成戦略は、使用パターンが出現するにつれて進化する傾向があります。ただし、事前に適用できる戦略と設計ガイドラインもあります。
適切なクラスタリングキーを選択します。通常、テーブルへの挿入の予想パターンに基づいて、設計時に適切なクラスター化インデックスを決定できます。将来の変化のために説得力のあるケースが出現した場合は、そうしてください。
プライマリおよびその他の一意の制約を作成します。これらは一意のインデックスによって実施されます。
外部キーと関連する非クラスター化インデックスを作成します。外部キーは最も頻繁に参照される結合列なので、最初からインデックスを付けます。
明らかに高度に選択的なクエリのインデックスを作成します。クエリパターンについては、非常に選択的であり、スキャンではなくルックアップを使用する可能性が高いことが既にわかっています。
上記を超えて、新しいインデックスを実装するために段階的かつ全体的なアプローチを取ります。全体として、追加を評価するときに、すべてのクエリと既存のインデックスに対する潜在的な利点と影響を評価することを意味します。
SQL Serverサークルで珍しいことではない問題は、インデックスDMVとSSMSのヒントが欠落していることからのガイダンスの結果としてのインデックスの過剰作成です。これらのツールはどちらも既存のインデックスを評価せず、既存の5列のインデックスに単一の列を追加するのではなく、新しい6列のインデックスを作成することをお勧めします。
-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
)
-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
Kimberly Trippには、インデックス作成戦略に関する優れた資料があり、SQLに焦点を当てている間は他のプラットフォームにも適用できます。SQL Serverユーザーには、上記の例のような重複を識別するための便利なツールがいくつかあります。
クエリの実行中に一時インデックスを作成することもできます。そのような技術の長所と短所は何ですか?
これは通常、めったに実行されないクエリ、通常はETLにのみ適用されます。以下を評価する必要があります。
両方のアプローチに関連するリスクは本当にあります。
オプションa)最初からインデックスを作成しますが、使用されていないインデックスを多数作成したことに気付いていません。これらはオーバーヘッドを追加します(データを変更するクエリに最も顕著ですが、最適なインデックスを特定しようとするSELECTステートメントの最適化も伴います)。
使用されなくなったインデックスを特定し、それらを削除しようとするためにあなた自身を鍛える必要があります(PostgreSQLはこれを行うことができます;残念ながら、MySQLは比較して非常に弱いです。)
オプションb)苦情が始まるまでインデックスを追加しないでください。または、特定のクエリが遅くなり改善できる可能性があることを診断ツールがトリガーします。
導入するリスクは、インデックスが必要であることに気付いてから追加するまでの間に十分な時間枠がないことです。
PostgreSQLはCONCURRENTLY
、インデックスの構築をサポートします。これにより、この突発的なインデックスの追加要件から生じるストレスの一部が軽減されますが、マニュアルには注意事項がいくつかあります。
オプション(b)が私の好みになる傾向がありますが、両方のオプションのハイブリッドがおそらく最良のソリューションだと思います。それは、インデックスが実際に使用されると思うかどうかに関するあなたの信頼レベルに関係しています。
これを特に複雑な議論にしているのは、通常、インデックスを変更するのは簡単ですが、スキーマを変更するのは難しいということです。b の遅延反応を無謀な言い訳として宣伝したくありません。
いくつか追加するだけです。
これが私のアプローチです。
未使用列のwhere句を入れ> 0
たり> ""
、配置することを恐れないでください。
select * from blah
where A="one"
and B="two"
and C>="" --to match index
and D="four"
--This will use your existing index. No need to create a redundant one.