3

通常、2 つまたは 3 つの異なる値のみを保持する「状態」列を持つテーブルを使用しています。場合によっては、このテーブルに数百万行が含まれていると、次の SQL ステートメントが遅くなります (完全なテーブル スキャンが実行されると仮定します)。

SELECT state, count(*) FROM mytable GROUP BY state

私は次のようなものを期待しています:

disabled |  500000
enabled  | 2000000

(基本的に、「有効」になっているアイテムの数と「無効」になっているアイテムの数を知りたいです。実際には、実際のアプリケーションではテキストではなく数字です)

状態列にインデックスを追加しても、そこには異なる値がほとんどないため、かなり役に立たないと思います。他にどのようなオプションがありますか?

「タイムスタンプ」列もあります (インデックス付き)。理想的には、次を追加すると、ソリューションもうまく機能するはずです。

WHERE timestamp BETWEEN x AND y

現在は SQLite3 データベースを使用していますが、他のデータベース エンジンもそれほど変わらないように見えるので、他の DB エンジンのソリューションも興味深いかもしれません。

ありがとうございました!

4

1 に答える 1

2

タイムスタンプ、状態 (この順序で) にカバリング インデックスを配置します。根拠は次のとおりです。

  • タイムスタンプの条件は、状態よりもはるかに選択的です

  • 状態がまだインデックス内にある場合 (つまり、インデックスをカバーしている場合)、エンジンはインデックス自体で範囲スキャンを生成するだけで済みます (テーブルのメイン データにアクセスするためのランダム I/O に料金を支払う必要はありません)。

注: タイムスタンプの範囲が広すぎると、インデックスに関係なく遅くなります。ランダム I/O はシーケンシャル I/O よりもコストがかかるため、インデックス レンジ スキャンがテーブル スキャンよりもコストが高くなるポイントがあります。経験則として、テーブルの 10% 以上をスキャンする必要がある場合、エンジンはテーブル スキャンを維持し、インデックスを無視することを検討する必要があります。ただし、sqliteはこの種の最適化をサポートするのに十分スマートであることに注意してください。

于 2012-10-30T17:49:41.060 に答える