「私たちは小さな効率を忘れるべきです。たとえば、約 97% の確率で: 時期尚早の最適化はすべての悪の根源です。」(ドナルド・クヌース)。私の SQL テーブルには、それぞれ数千行を超える行が含まれる可能性は低いです (そして、それらは大きなものです!)。SQL Server データベース エンジン チューニング アドバイザーは、データの量を無関係なものとして却下します。したがって、これらのテーブルに明示的なインデックスを配置することについても考えるべきではありません。正しい?
13 に答える
インデックスの価値は読み取りの高速化にあります。たとえば、日付列の日付の範囲に基づいて多数の SELECT を実行している場合、その列にインデックスを配置することは理にかなっています。そしてもちろん、一般的には、JOIN を実行する列にかなりの頻度でインデックスを追加します。効率の向上は、通常のレコードセットのサイズとレコード数の比率にも関連しています (つまり、20/2000 レコードを取得すると、90/100 レコードを取得するよりもインデックス作成のメリットが大きくなります)。インデックスのない列のルックアップは、基本的に線形検索です。
すべての INSERT は各列インデックスへの内部挿入も必要とするため、インデックスのコストは書き込みにかかります。
したがって、答えは完全にアプリケーションによって異なります。たとえば、読み取り回数が書き込み回数の 100 倍または 1000 倍になる可能性がある動的 Web サイトのような場合で、データ列に基づいて頻繁に異なるルックアップを行っている場合、インデックス作成は有益な場合があります。 . ただし、書き込み数が読み取り数を大幅に上回っている場合、チューニングはこれらのクエリの高速化に重点を置く必要があります。
JOIN/WHERE 列にインデックスがある場合とない場合の両方で、アプリの最も頻繁な操作を特定してベンチマークするのにほとんど時間はかかりません。そうすることをお勧めします。また、運用アプリを監視し、最も高価で最も頻繁なクエリを特定し、これら 2 つのクエリ セットの共通点に最適化の取り組みを集中させることも賢明です (これは、インデックスや、より多くのまたはより少ないメモリを割り当てるなど、まったく異なるものを意味する可能性があります)。クエリまたは結合キャッシュ)。
Knuth の賢明な言葉は、インデックスの作成 (または作成しない) には当てはまりません。インデックスを追加しても、何も直接最適化されないからです。つまり、DBMS オプティマイザがクエリを最適化するために使用するインデックスを提供していることになります。実際、小さなテーブルにインデックスを付けないことを決定することは、最適化が時期尚早であると主張した方がよいでしょう。そうすることで、DBMS オプティマイザのオプションが制限されるからです!
異なる DBMS には、テーブル サイズなどのさまざまな要因に基づいて列にインデックスを付けるかどうかを選択するための異なるガイドラインがあり、これらを考慮する必要があります。
データベースの時期尚早な最適化の例: 正規化されたデータベースに実際にパフォーマンスの問題があることをベンチマークが示す前の「パフォーマンスのための非正規化」。
Primary key columns will be indexed for the unique constraint. I would still index all foreign key columns. The optimizer can choose to ignore your index if it is irrelevant.
If you only have a little bit of data then the extra cost for insert/update should not be significant either.
絶対に間違っています。100%間違っています。何百万もの無意味なインデックスを配置しないでください。ただし、(ほとんどの場合) 主キーが必要であり、正しくクラスター化する必要があります。
理由は次のとおりです。
SELECT * FROM MySmallTable <-- No worries... Index won't help
SELECT
*
FROM
MyBigTable INNER JOIN MySmallTable ON... <-- Ahh, now I'm glad I have my index.
これは良いルールです。
「私はTABLEを持っているので、いつかそれを照会したいと思うでしょう...照会する場合は、おそらく一貫した方法でそうするでしょう...」 <- - テーブルにインデックスを付ける方法です。
編集: 次の行を追加します: 具体的な例を念頭に置いている場合は、インデックスを作成する方法と、インデックスを作成することでどれだけ節約できるかを示します。表と、その表をどのように使用する予定かの例を提供してください。
場合によります。テーブルは参照テーブルですか?
インデックスがない1000行のテーブルがあり、結果のテーブルスキャンは、ユーザーを5秒ではなく5分遅らせる非常に単純な操作の違いを生む可能性があります。SQL Server以外のDBMSを使用して、この問題を正確に確認しました。
一般に、テーブルが参照テーブルである場合、そのテーブルの更新は比較的まれです。これは、インデックスを更新するためのパフォーマンスへの影響も比較的まれであることを意味します。オプティマイザーがインデックスを通過した場合、オプティマイザーのパフォーマンスへの影響はごくわずかです。インデックスを保存するために必要なスペースもごくわずかです。
主キーを宣言する場合は、そのキーの自動インデックスを取得する必要があります。その自動インデックスは、ほとんどの場合、そのコストを正当化するのに十分な効果を発揮します。そのままにしておきます。主キーなしで参照テーブルを作成する場合、設計方法に他の問題があります。
主キー以外の列のセットで頻繁に検索または頻繁に結合を行う場合は、追加のインデックスがそれ自体の代償を払う可能性があります。問題でない限り、その問題を修正しないでください。
一般的な経験則は次のとおりです。そうしない理由が見つからない限り、DBMSのデフォルトの動作を使用してください。それ以外のものは、あなたの側での最適化に対する時期尚早の先入観です。
インデックス作成に関する通常のルールに従うことをお勧めします。これは、おおよそ「クエリで使用する列にインデックスを作成する」ことを意味します。
これは、このような小さなデータベースでは不要に思えるかもしれません。他の人がすでに言っているように、データベースがあなたが説明したほど小さいままである限り、とにかくクエリは十分に高速であり、インデックスは実際には必要ありません. 挿入や更新が遅くなる可能性もありますが、非常に具体的な要件がない限り、このような小さなデータベースでは問題になりません。
しかし、データベースが大きくなった場合 (データベースは時々そうなる傾向があります)、おそらくそれまでに忘れていた古いデータベースにインデックスを追加することを覚えておく必要はありません。顧客の 1 人にインストールされていて、変更できない場合もあります。
私が言いたいのは、インデックスはデータベース設計のごく自然な部分であるべきであり、時期尚早であるかどうかにかかわらず、最適化であるインデックスの欠如であるということです。
行の幅が狭く、たとえば 10 ~ 20 の 8K ページに数千行が収まる場合、作成したとしても SQL オプティマイザーがインデックスの使用を選択する可能性はほとんどありません。
必要な場合にのみインデックスを配置してください:)
テーブルの用途によっては、インデックスを配置すると実際にパフォーマンスが低下する場合があります...
つまり、必要なときにテーブルにインデックスを配置することを検討してください。アプリケーションのプロファイリングによって決定されます。
UNIQUE 制約を使用すると、インデックスが暗黙的に作成されることがよくあります。その場合、私はそれらの使用を避けようとしません!
一般的な経験則として、小さいインデックスは通常使用されないため、避けることをお勧めします。
しかし、私がここで概説したように、時にはそれらは大きな後押しを提供することができます.
インデックスがあっても、そのテーブルの統計によっては、SQL Server がそれを使用しないことさえあります。また、年に数回しか実行されないレポートにインデックスを追加する予定がある場合は、インデックスを追加するための INSERT/UPDATE ペナルティが常に適用されることに注意してください。インデックスを追加する前に、パフォーマンスが低下する価値があるかどうかを自問してください。
テーブルの主キーに自動インデックスがあると思いますが、データの少ないテーブルをクエリする場合はこれで十分です。
したがって、作業するデータセットが小さい場合は、明示的なインデックスを避けることができます。
クエリに基づいて 2 つの検索が行われる可能性があることを理解する必要があります。クエリ対象のデータがインデックス列にある場合、追加の手順は必要ない場合があります。
オプティマイザーがインデックスを追跡したとしても、データのダブルディッピングが遅くなる可能性は十分にあります。気にするかどうかは、アプリケーションのプロファイリングと最終的な説明計画次第です。