为只有一个匹配的Between查询索引SQL?

时间:2012-10-18 15:05:18

标签: sql indexing between

我们有一个包含超过两百万行的表,其中所有针对它的查询都是使用Column1Column2进行的查询。此外,只有一个可能的结果。例如......

Col1     Col2
1        5
6        10
11       15

select * from table1 where 8 between Col1 and Col2

我目前在Col1Col2上拥有唯一的聚集索引。到目前为止,我一直无法弄清楚如何进一步调整查询和索引以最小化处理的行。执行计划目前报告在找到一个且只有正确答案时处理的成本几乎为0.5和113k行。

我可以忽略哪些选项?

根据要求,当前执行计划中的一些细节:

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))

3 个答案:

答案 0 :(得分:7)

范围是否始终不重叠?你提到总有一场比赛。如果是,您可以将其写为:

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

这将为您提供Col2的最低值(大于8)的行 - 这是您感兴趣的范围。仅Col2需要索引,并且成本应该是小。

由于您没有提及您正在使用的DBMS,因此LIMIT 1应替换为您用于获取前N个结果的数据库。

您必须在代码中检查Col1 <= your_value,以确保您要查找的值确实在此范围内。

答案 1 :(得分:3)

我想我找到了答案。我必须首先在Col1上创建一个Unique Clustered Index,然后在Col2上创建一个Unique Unclustered Index。然后必须更新查询以强制查找每个索引。

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行处理。

答案 2 :(得分:1)

select * from table1 where Col1 <= 8 and Col2 >= 8

可能两列之间的“之间”导致了问题。

此外,您应该在两列(Col1,Col2)上只有1个复合索引。