更新:
計算列を使用したクエリの効率的なインデックス作成戦略については、私のブログのこの記事を参照してください:
主なアイデアは、丸められた length
を計算するだけです。 および startDate
範囲を指定してから、等式条件を使用してそれらを検索します (これは B-Tree
に適しています) インデックス)
MySQL
で および SQL Server 2008
で SPATIAL
を使用できます インデックス (R-Tree
).
これらは、「レコードの範囲内の特定のポイントを持つすべてのレコードを選択する」などの条件に特に適しています。これはまさにあなたのケースです.
start_date
を保存します と end_date
LineString
の最初と最後として (UNIX
に変換します) 別の数値のタイムスタンプ)、SPATIAL
でそれらにインデックスを付けます そのようなすべての LineString
を索引付けして検索します 最小境界ボックス (MBR
) MBRContains
を使用して、問題の日付値が含まれています .
MySQL
でこれを行う方法については、ブログのこのエントリを参照してください。 :
SQL Server
の簡単なパフォーマンスの概要 :
特定の IP
の検索にも同じソリューションを適用できます データベースに保存されているネットワーク範囲に対して。
このタスクは、クエリとともに、そのような条件の別のよく使用される例です。
プレーン B-Tree
範囲が重複する可能性がある場合、インデックスは適切ではありません。
彼らができない場合 (そしてあなたはそれを知っています)、@AlexKuznetsov
によって提案された素晴らしい解決策を使用できます。
また、このクエリのパフォーマンスは、データの分散に完全に依存することに注意してください。
B
にたくさんのレコードがある場合 A
のいくつかのレコード 、 B.dates
にインデックスを作成するだけです TS/CIS
を A
で 行ってください。
このクエリは常に A
からすべての行を読み取ります Index Seek
を使用します B.dates
に ネストされたループで。
データが逆方向に分散されている場合、i. e. A
にたくさんの行があります しかし B
には少ない であり、範囲が一般的に短い場合は、テーブルを少し再設計できます:
A
start_date interval_length
、 A (interval_length, start_date)
に複合インデックスを作成します
このクエリを使用します:
SELECT *
FROM (
SELECT DISTINCT interval_length
FROM a
) ai
CROSS JOIN
b
JOIN a
ON a.interval_length = ai.interval_length
AND a.start_date BETWEEN b.date - ai.interval_length AND b.date