これまで、特定のインデックスに対してこれを実行して、頻繁に実行される大量のクエリを支援しました。実際に彼らが行ったことは、複数のクラスター化インデックスを作成することです。これらのインデックスのいずれかを使用して行を検索する場合、実際のクラスター化インデックス(または実際のクラスター化インデックスがない場合はヒープ)の残りのデータを検索する追加の作業は必要ありません。 。
これは賢明な戦略ですか?
特定のクエリパターンをサポートする必要がある一部のインデックスでは、確かにそうです。
しかし、すべてのインデックスでこれを行うために、私は確かにノーと言うでしょう。
実際に必要のない場所で行うにはスペースが無駄になり、挿入/更新が大幅に遅くなります。各インデックスページが保持するレコードが少なくなるため、フィルター処理のためにインデックスのチャンクを参照する必要があるが、他のすべての列を使用する必要がないクエリは、より多くのページにアクセスする必要があるため、読み取りクエリが遅くなる可能性があります。これにより、データベースのメモリ消費量が増加します。これらのページはバッファプールにロードする必要があり、メモリが不足している場合、他の有用なページを排出する可能性があります。これらのインデックスで圧縮を使用して、ストレージとメモリの要件への影響を軽減しようとすると、代わりにCPUに余分な負荷がかかります。
デフォルトでは(常にではないが)すべての列を取得するORMを介してアクセスするため
これはORM(または単純なORM)の最適化が不十分な一般的なパターンであり、これらの場合、SQL Serverのインデックスアドバイザー(および同様のサードパーティツール)が多数のINCLUDE
d列を持つインデックスを提案するので、あなたの意見に同意しますこれが、このようにしてインデックスが作成された理由です。
しかし、そのようなクエリはすべて少し速くなり、一部は大幅に速くなる可能性がありますが、多くの場合、メリットは非常に小さいため、共通のワーキングセット、ディスク上のスペースに必要な追加のメモリフットプリントに値しないと思いますディスクとメモリ間のIO。
また、ORMは、クエリが関連するすべてのテーブルのすべての列を選択していない可能性があるため、現在のリクエストのメインターゲットにのみメリットがあり、他のオブジェクトがフィルタリングに使用されている場合、インデックスが大きいとクエリにペナルティが科される可能性があることにも注意してください。データを返さない(SELECT * FROM table1 WHERE id IN (SELECT someID FROM table2 WHERE someColumn='DesiredValue')
おそらく)。
特にデータが大きい場合に使用される余分なスペースについてのもう1つの考慮事項は、バックアップ戦略に影響を与えることです。つまり、これらのバックアップのストレージと転送のコスト、潜在的な復元時間などです。
2つの[オンプレミスとAzureSQL]の違いに備えるべきか
一般に、ここでの考慮事項はいずれの場合も同じになると思いますが、Azureでは、大きなインデックスによって課される過剰なメモリ/ IOコストがより直接的に見えるため、サービス層を微調整できるため、インフラストラクチャコストをより簡単に調整できますハードウェアリソースのセットが比較的固定されている。vcoreベースの価格設定の代わりに標準/プレミアム階層を使用する場合、プレミアムにはDTUあたりのIOが大幅に増えるため、標準のIOコストの影響が大きくなります。Azureでマルチリージョンバックアップ、冗長性、またはその他のローカル以外の機能を使用している場合は、不必要に広いインデックスが占める余分なスペースに関連する帯域幅コストが発生する可能性があります。
SELECT
指定なしでORDER BY
以前と同じ行が返されますが、任意の順序が異なります。