私の質問は、データベースがデータを保存する方法と、内部でクエリを実行する方法です。
テーブルに次のフィールドがあるとします。
- ID
- 名前
- 年
- 重さ
- マネジャー
クエリを実行しますselect * from Table1 where age>50 and weight<100
内部でクエリを実行する方法に興味があります。
この例では、B-Tre/B+Tree のノードには何が含まれますか?
私の質問は、データベースがデータを保存する方法と、内部でクエリを実行する方法です。
テーブルに次のフィールドがあるとします。
クエリを実行しますselect * from Table1 where age>50 and weight<100
内部でクエリを実行する方法に興味があります。
この例では、B-Tre/B+Tree のノードには何が含まれますか?
選択した例は、単一のツリー (2 つの独立した範囲) では機能しない数少ないケースの 1 つです。
ただし、進行中の電子書籍の最初の章では、B ツリー インデックスの内部の仕組みについて説明しています: http://use-the-index-luke.com/anatomy/
上記の例で 2 つのインデックスが役立つ理由の詳細については、EDITを参照してください。
上記のクエリは、次の 3 つのインデックス構成でサポートできます。
連結されたインデックスAGE
、次にWEIGHT
(この順序で)。
場合によっては、クエリはすべてのレコードWHERE AGE > 50
を読み取り、次に でフィルタリングしWEIGHT
ます。
連結されたインデックスの次WEIGHT
にAGE
(別の順序)。
それは別の方法です: すべてのレコードWHERE WEIGHT < 100
を読み取り、次に でフィルタリングしAGE
ます。
より効率的なものは、所有しているデータによって異なります。レコードが少ない場合は最初のAGE > 50
ほうWEIGHT < 100
が効率的で、それ以外の場合は 2 番目の方が効率的です。ただし、異なる値でクエリを実行すると、状況が変わる可能性があります。
連結インデックスがクエリを十分にサポートできない理由は、各インデックスの順序が 1 つの軸のみにあるためです。各インデックス エントリは、別のエントリの前または後にありますが、隣接することはありません。すべてのインデックス エントリが 1 つのチェーンを構築します。
2 つの独立した範囲クエリを持つクエリには、2 つの軸が必要です。これはチェーンではなく、チェス盤のようなものです。一方の軸AGE
はもう一方の軸ですWEIGHT
。それが可能であれば、クエリはチェス盤の 1 つのコーナーのみをスキャンする必要があります。
ただし、b ツリーには軸が 1 つしかないため、最初に使用する基準を選択する必要があります。を選択AGE
すると、 から始まり、AGE 50
チェーン全体が最後までスキャンされます。チェーンの側に保存されているレコードの一部のみが の対象WEIGHT < 100
となります。その他のレコードは読み取る必要がありますが、破棄されます。
したがって、1 つのツリーが 2 つの独立した範囲句を持つクエリをサポートできない理由を説明する長い話です。一方、1 つの連結インデックスは、次のことを非常にうまく行うことができます。
WHERE age = 50 AND weight < 100
WHERE weight = 100 AND age > 50
WHERE age > 50 AND age < 70;
ただし、2 つの異なる列で 2 つの不等式演算子が使用されている場合、問題が発生します。
じゃあ何をすればいいの?
3 番目に考えられる方法は、2 つの列に 2 つの独立したインデックスを設定することです。これにより、好きなだけ軸を持つことができます (インデックスをさらに作成するだけです)。ただし、それにはいくつかの大きな問題があります。まず第一に、すべての DB 製品がそれをサポートしているわけではありません。サポートされている場合は常に、かなり広範な操作です。通常、各インデックスがスキャンされ、結果ごとにビットマップインデックスが構築されるように機能します。次に、これらのビットマップ インデックスを結合して、AND
演算子を適用します。これは多くのデータ変更です。各条件がそれ自体に対してあまり選択的でない場合にのみ努力する価値がありますが、両方を合わせると非常に選択的です。
私のアドバイスはありませんか?
クエリが OLTP 環境で実行される場合: 1 つの連結インデックスを使用します。2 つの独立したインデックスは、最後の手段としてのみ使用できます。ただし、OLAP 環境で作業している場合は、とにかくビットマップ インデックスが必要になることがあります。
ps .: インデックス作成は私の本 (解決策付き) の演習AGE
でした。特に、保存は悪い習慣であるため、代わりに生年月日を保存する必要があります。AGE