多数の行を含むテーブルがあり、インデックスを作成する列の1つに20の値の1つを含めることができるとします。列にインデックスを付けるとしたら、それは大きくなりますか?
もしそうなら、なぜですか?データを20個のテーブル(列の値ごとに1つ)に分割すると、インデックスサイズは簡単になりますが、インデックスの効果は同じになります。
多数の行を含むテーブルがあり、インデックスを作成する列の1つに20の値の1つを含めることができるとします。列にインデックスを付けるとしたら、それは大きくなりますか?
もしそうなら、なぜですか?データを20個のテーブル(列の値ごとに1つ)に分割すると、インデックスサイズは簡単になりますが、インデックスの効果は同じになります。
ひどいのはインデックスではありません。間違った列にインデックスを付けているのはひどいことです。
まじめな話ですが、なぜ 1 列のテーブルが必要なのでしょうか? そのデータの意味は何ですか?それはどのような目的に役立ちますか?
そして20テーブル?最初にデータベース設計を読むか、質問のコンテキストを説明することをお勧めします。
インデックス (またはインデックス) は悪くありません。多くの非常に賢い人々が、過去数十年間、本当に驚くべき時間を費やして、これを実現してきました。
ただし、同じ量の専門知識と労力が不足しているスキーマは、実際には非常にうまくいかない場合があります。
この場合のパーティショニングは、クラスター化インデックスを適用することと同じです。テーブルが別の方法で (または任意の順序で) 並べ替えられている場合、インデックスは必然的により多くのスペースを占有する必要があります。プラットフォームによっては、インデックス付きの値に対する行の並べ替えが増えるにつれて、非クラスター化インデックスのサイズが小さくなる場合があります。
YMMV。
悪いインデックスはありませんが、使用方法に注意を払う必要があります。そうしないと、クエリのパフォーマンスが低下する可能性があります。
最初に: スキーマ/設計
なぜ列が 1 つしかないテーブルを作成するのでしょうか? それはおそらく、正規化を一歩先に進めています。データベースの設計は、パフォーマンスを最適化する上で考慮すべき最も重要なことの 1 つです。
2 つ目: インデックス
簡単に言えば、インデックスは、データベースがレコードのバイナリ検索を実行するのに役立ちます。列 (または列のセット) にインデックスがないと、データベースはテーブル スキャンにフォールバックすることがよくあります。テーブル スキャンは、すべてのレコードを列挙するため、非常にコストがかかります。
データベーステーブルにいくつのレコードがあるかは、インデックススキャンにとってそれほど重要ではありません。(バランスの取れた) 二分木検索のため、レコードの量を 2 倍にしても、追加の検索ステップは 1 つだけになります。
テーブルの主キーを決定すると、SQL はその列にクラスター化インデックスを自動的に配置します。クラスタ化インデックスは非常に優れたパフォーマンスを発揮します。さらに、SELECT、JOIN、WHERE、GROUP BY、および ORDER BY ステートメントで頻繁に使用される列に非クラスター化インデックスを配置できます。インデックスには特定の重複があることに注意してください。クラスター化インデックスを非クラスター化インデックスに含めないようにしてください。
また、インデックスの FILL FACTOR も興味深いかもしれません。テーブルを読み取り (高いフィル ファクター - 少ないストレージ、少ない IO) 用に最適化するか、書き込み用 (低いフィル ファクター - より多くのストレージ、データベース ページの再構築を少なくする) に最適化しますか。
3 番目: パーティショニング パーティショニング
を使用する理由の 1 つは、データ アクセスを最適化することです。100 万件のレコードがあり、そのうち 500,000 件のレコードはもはや関連性がなく、アーカイブ目的で保存されているとします。この場合、テーブルを分割し、古い 500,000 レコードを低速ストレージに格納し、残りの 500,000 レコードを高速ストレージに格納することを決定できます。
測定することは知ること
です何が起こるかについての洞察を得る最良の方法は、CPU と io に何が起こるかを測定することです。Microsoft SQL サーバーには、Management Studio のプロファイラーや実行プランなどのツールがあり、クエリの期間、読み取り/書き込みの回数、CPU 使用率を確認できます。また、実行計画は、どのインデックスまたは IF インデックスが使用されているかを示します。驚いたことに、予期していなかったテーブル スキャンが表示される場合があります。
簡単な答え: インデックスはダメですか: はい、いいえ
より長い答え: 適切に使用すれば吸わない. インデックスがどのように機能するか、なぜ機能するのか、なぜ機能しないのかについて読み始める必要があるかもしれません。
多数の行を含むテーブルがあり、インデックスを作成する1つの列に20個の値のいずれかを含めることができるとします。列にインデックスを付けるとしたら、それは大きくなりますか?
インデックスサイズは、行数とインデックス値の長さに比例します。
インデックスは、インデックス付けされた値だけでなく、行へのある種のポインタ(ROWID
in Oracle
、LCID
in PostgreSQL
、primary key inInnoDB
など)も保持します。
10,000
行と1つの異なる値がある場合でも、インデックスにはレコード10,000
があります。
もしそうなら、なぜですか?データを20個のテーブル(列の値ごとに1つ)に分割すると、インデックスサイズは簡単になりますが、インデックスの効果は同じになります。
この場合、元のインデックスと合計で同じサイズの20個のインデックスが付属します。
この手法は、実際には、このようないわゆるパーティションインデックスで使用されることがあります。それには長所と短所があります。
標準の B ツリー インデックスは、この例では当てはまらないかなり選択的なインデックスに最適です。使用している DBMS については言及しません。Oracle には、ビットマップ インデックスと呼ばれる別のタイプのインデックスがあります。これは、OLAP 環境の選択性の低いインデックスにより適しています (これらのインデックスは維持にコストがかかるため、OLTP 環境には適していません)。
オプティマイザーは、インデックスが最速でデータを取得するのに役立つと考えるかどうかを統計に基づいて決定します。そうでない場合、オプトマイザーはそれを使用しません。
パーティショニングは別の戦略です。Oracleでは、いくつかの列セットでパーティション化されたテーブルを定義でき、オプティマイザの場合、提案したように「パーティションの削除」を自動的に実行できます。
申し訳ありませんが、「大きい」の意味がよくわかりません。
インデックスがクラスター化されている場合、各レコードのすべてのデータが同じリーフ ページにあるため、クエリを適切に記述している限り、テーブルで使用できる最も効率的なインデックスが作成されます。
インデックスがクラスター化されていない場合、インデックス関連のデータのみがリーフ ページに表示されます。次に、他のインデックスの数などと、フィル ファクターなどの詳細に応じて、インデックスが効率的である場合とそうでない場合があります。一般に、テーブルに大量のインデックスがない場合は安全です。
インデックスの効率は、列に入力する 20 個の値のデータ型によっても決まります。それらが事前定義された値である場合、それらの詳細はおそらく単純な主キー データ型 (Int/Number など) を持つルックアップ テーブルにあるはずです。次に、その列を、列にインデックスを持つ外部キーとしてテーブルに追加します。
最終的に、列に完全なインデックスを作成できます。ただし、最適な使用方法は、ほとんどの場合、作成するクエリによって決まります。したがって、クエリでインデックスを使用する場合は、ゴールデンです。
インデックスは純粋にパフォーマンスのためのものです。インデックスが関心のあるクエリのパフォーマンスを向上させない場合、それは最悪です。
ディスクの使用に関しては、懸念事項を比較検討する必要があります。SQLプロバイダーが異なれば、インデックスの作成方法も異なりますが、クライアントとしては、一般的に、可能な限り最善を尽くしていると信じています。あなたが説明している場合、クラスター化されたインデックスはサイズとパフォーマンスの両方に最適である可能性があります。
ソートされた順序で、すべての行のこれらの値を保持するのに十分な大きさです。
4文字の20の異なる文字列と100万行があるとすると、これらの値を保持するには少なくとも400万バイト(または16ビットUnicodeの場合は8)になります。