sql >> データベース >  >> RDS >> Sqlserver

SQL Server の同じ列に複数の非クラスター化インデックスを作成する

    単語はかなり論理的で、すぐに習得できます。 :)

    簡単に言うと、SEEK はレコードの正確な場所を探すことを意味します。これは、検索対象の列がインデックス化されていて、フィルター (WHERE 条件) が十分に正確である場合に SQL Server が行うことです。

    SCAN は、各値を個別に検索するのではなく、範囲全体をフェッチする方が高速であるとクエリ実行プランナーが推定する行のより広い範囲を意味します。

    はい、同じフィールドに複数のインデックスを設定できます。場合によっては、非常に良いアイデアになることもあります。インデックスを試して、クエリ実行プランナーを使用して何が起こるかを判断します (SSMS のショートカット:Ctrl + M)。同じクエリの 2 つのバージョンを実行することもできます。実行プランナーは、それぞれがどれだけのリソースと時間を消費しているかを簡単に表示するので、最適化が非常に簡単になります。

    しかし、これらを少し拡張すると、次のようなアドレス テーブルがあり、10 億を超えるレコードがあるとします。

    CREATE TABLE ADDRESS (ADDRESS_ID INT -- CLUSTERED primary key ADRESS_PK_IDX , PERSON_ID INT -- FOREIGN KEY, NONCLUSTERED INDEX ADDRESS_PERSON_IDX , CITY VARCHAR(256) , MARKED_FOR_CHECKUP BIT , **+n^10 他の異なる列.. .**)  

    ここで、個人 12345 の住所情報をすべて見つけたい場合は、PERSON_ID のインデックスが最適です。テーブルには同じ行に他のデータがロードされているため、非クラスター化インデックスを作成して他のすべての列と PERSON_ID をカバーするのは非効率的であり、スペースを消費します。この場合、SQL Server は PERSON_ID のインデックスでインデックス SEEK を実行し、それを使用して ADDRESS_ID のクラスター化インデックスでキー ルックアップを実行し、そこから同じ行の他のすべての列のすべてのデータを返します。

    ただし、都市内のすべての人を検索したいが、他の住所情報は必要ないとします。今回は、CITY にインデックスを作成し、INCLUDE オプションを使用して PERSON_ID もカバーするのが最も効果的な方法です。そうすれば、同じ行の PERSON_ID データの CLUSTERED インデックスをチェックする必要なく、1 回のインデックス シーク/スキャンで必要なすべての情報が返されます。

    ここで、これらのクエリが両方とも必要であるとしますが、10 億件のレコードがあるため、それでもかなり重いとします。しかし、非常に高速である必要がある特別なクエリが 1 つあります。このクエリは、MARKED_FOR_CHECKUP された住所にあり、ニューヨークに住んでいる必要があるすべての人を必要とします (検査の意味は無視してください。それは問題ではありません)。ここで、MARKED_FOR_CHECKUP と CITY で 3 番目のフィルター処理されたインデックスを作成し、INCLUDE で PERSON_ID をカバーし、フィルターで CITY ='New York' および MARKED_FOR_CHECKUP =1 を作成することをお勧めします。このインデックスはクエリのみをカバーするため、非常に高速です。これらの正確な条件を満たすため、他のインデックスと比較して通過するデータの割合が少なくなります。

    (ここでの免責事項。クエリ実行プランナーは愚かではないことに注意してください。複数の非クラスター化インデックスを一緒に使用して正しい結果を生成できます。したがって、上記の例は、いつ必要になるかを想像するのが非常に難しいため、利用可能な最良のものではない可能性があります。同じ列をカバーする 3 つの異なるインデックスですが、おわかりいただけると思います。)

    インデックスの種類、それらの列、含まれる列、並べ替え順序、フィルターなどは状況に完全に依存します。いくつかの異なるタイプのクエリを満たすために、カバリング インデックスを作成する必要があります。各インデックスは HDD のスペースを占有するため、役に立たないインデックスを作成するのは無駄であり、データ モデルが変更されるたびに余分なメンテナンスが必要になり、最適化と統計の更新操作に時間がかかります... したがって、すべてにインデックスを平手打ちしたくはありません。

    実験し、学び、ニーズに最適なものを見つけてください。



    1. 関連するtnsnames.oraファイルの場所を特定する

    2. AjaxLoadの代わりにページを更新します

    3. GraphQL-引数に依存する計算された型を返します

    4. PostgreSQLで現在の時刻を取得する方法