如何在sql server上增加范围查询性能?

时间:2016-05-18 09:43:54

标签: sql-server indexing lookup

我有一个数据库,我有一个超过2米的行。它有startIpNumendIpNum列(范围不重叠)。我正在对该表进行一些查询:

表:

Id | startIpNum(Numeric(0,18)) | endIpNum(Numeric(0,18)) | locId

查询1:

select locId from Blocks
where startIpNum <= 1550084098 and endIpNum >= 1550084098 

查询2(添加了此查询,希望获得更好的结果):

select top 1 locId from Blocks
where endIpNum >= 1550084098 

这些查询需要合理的时间,没有问题。但是每次打开网页时我都需要获得大约100个不同的行,并且需要大约15秒,这可能是预期的,但不是所希望的。

我相信通过使用索引我可以提高性能,所以我添加了2个索引,一个到start(asc)一个到end(desc),但性能相同。

我还能做些什么来实现更好的查询性能?

更新

我已经运行了你们提出的create index查询。现在没有变化。

根据要求,我在下面包含sql查询执行计划(因为我不熟悉执行计划的事情,我只是从ssms截取屏幕截图,继续询问是否需要其他东西来回答我的情况):

Query1的执行计划:

enter image description here

Query2的执行计划:

enter image description here

2 个答案:

答案 0 :(得分:0)

如上所述,如果没有执行计划来看这个略微偏盲,但基本要点是:

1)如果索引到位以支持此查询,则添加两个没有任何意义。只能使用其中一个索引。因此,您需要一个包含两列的索引。

2)返回“*”意味着密钥查找将是不可避免的,因为使用索引来获取它需要的行,它必须从聚簇索引中获取索引中未包含的数据。如果要带回大量行,密钥查找会变得非常昂贵。如果您可以限制返回的列,则可以使用INCLUDE来避免键查找。您不需要在此列表中包含主键,因为这仍然是索引的一部分。

说完这个,你最好的选择就是:

CREATE INDEX ix_range ON dbo.yourTable (start, end) INCLUDE (<list_of_columns_in_your_select)

查看您的查询计划,很明显,您的参数CONVERT_IMPLICIT@1正在执行@2。应避免这些,请执行以下操作:

DECLARE @1numeric numeric(18, 0), 
        @2numeric numeric(18, 0)

SELECT @1numeric = CAST(@1 AS numeric(18, 0)),
       @2numeric = CAST(@2 AS numeric(18, 0))

SELECT locId FROM Blocks
WHERE startIpNum <= @1numeric and endIpNum >= @2numeric 

答案 1 :(得分:-1)

尝试显式转换值以匹配列。

select * from that_table
where CAST(123123123 as Numeric(18,0)) between start and end

我认为由于隐式转换,sqlserver正在丢失索引查找。