11

200 万行を超えるテーブルがあり、それに対するすべてのクエリは と を使用した Between ルックアップにColumn1なりColumn2ます。また、可能な結果は 1 つだけです。例えば...

Col1     Col2
1        5
6        10
11       15

select * from table1 where 8 between Col1 and Col2

現在、 と に一意のクラスター化インデックスがCol1ありCol2ます。これまでのところ、クエリとインデックスをさらに調整して、処理される行を最小限に抑える方法を理解できていません。実行計画は現在、唯一の正解を見つけるときに処理される約 0.5 行と 113,000 行のコストを報告しています。

見落としている可能性のあるオプションは何ですか?

リクエストに応じて、現在の実行計画の詳細:

Operation
 Clustered Index Seek
Predicate
 CONVERT_IMPLICIT(bigint,[@2],0)<=[Col2]
Seek Predicate
 Seek Keys[1]: End: Col1 <= Scalar Operator(CONVERT_IMPLICIT(bigint,[@1],0))
4

3 に答える 3

7

範囲は常に重複していませんか? 常に一致するのは 1 つだけだとおっしゃいました。もしそうなら、あなたはそれを次のように書くことができます:

SELECT * FROM table1 
   WHERE 8 <= Col2 
   ORDER BY Col2 ASC
   LIMIT 1

これにより、最も低い値がCol28 を超える行が得られます。これは、関心のある範囲です。インデックスは でのみ必要でCol2あり、コストは小さいはずです。

使用している DBMS について言及していないためLIMIT 1、DB が最初の N 個の結果を取得するために使用するものに置き換える必要があります。

コードをチェックインCol1 <= your_valueして、探している値が実際に範囲内にあることを確認する必要があります。

于 2012-10-18T15:18:01.670 に答える
3

私は答えを見つけたと思います。まず、Col1 に一意のクラスター化インデックスを作成し、次に Col2 に一意の非クラスター化インデックスを作成する必要がありました。次に、クエリを更新して、各インデックスのルックアップを強制する必要がありました。

select * from table1 where Col1 = 
    (select max(Col1) from table1 where Col1 <= 8)
and Col2 = 
    (select min(Col2) from table1 where Col2 >= 8)

実行計画は、0.0098 コストと 1 行の処理を報告するようになりました。

于 2012-10-18T22:04:10.910 に答える
1
select * from table1 where Col1 <= 8 and Col2 >= 8

2 つの列の「間」が問題を引き起こしている可能性があります。

また、両方の列 (Col1、Col2) に複合インデックスを 1 つだけ持つ必要があります。

于 2012-10-18T15:12:45.360 に答える