【问题标题】:How to increase range query performance on sql server?如何提高 sql server 上的范围查询性能?
【发布时间】:2016-09-14 17:15:09
【问题描述】:

我有一个数据库,其中有超过 2m 行。它有startIpNum 和endIpNum 列(范围不重叠)。我正在对该表进行一些查询:

表:

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的执行计划:

Query2的执行计划:

【问题讨论】:

  • CREATE INDEX ix ON dbo.tbl (start, end) INCLUDE (id, value)
  • 更详细的答案请提供您的实际执行计划
  • SSMS 可以在索引缺失时为您建议索引 - 只需包括执行计划并单击显示缺失的索引详细信息。
  • 您也可以让表格只返回所需的列而不是所有列,如果您不使用所有列,这通常会节省时间。将值显式转换为 Numeric(0,18) 也可能值得,否则它可能会尝试将值解析为 int 并将其隐式转换为数字。您可能还会看到使用 where start &gt;= 123123123 AND end &lt;= 123123123 的改进,因为它不需要在每一行上运行两次计算(尽管执行计划应该即时转换它,它可能不再那么明确可能会有所帮助)。跨度>
  • 它正在使用索引,因此在相对较小的表上运行查询需要 15 秒的时间。您可以在select 查询之前运行set statistics io on 和set statistics time on 并发布结果(来自“消息”选项卡)吗?

标签: sql-server indexing lookup


【解决方案1】:

如前所述,如果没有执行计划来查看这会有点盲目,但基本点是:

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

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

话虽如此,你最好的选择是这样的:

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

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

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 

【讨论】:

    【解决方案2】:

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

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

    我假设 sqlserver 由于隐式转换而丢失了索引查找。

    【讨论】:

    • 这是不正确的。首先,并非所有条件内的函数都会失去可分析性,您应该在做出错误陈述之前阅读它。转换标量值对可搜索性没有影响,而是条件匹配。优化器将“BETWEEN”解析为 >= /
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2014-03-23
    • 1970-01-01
    • 2011-03-03
    • 2019-03-20
    • 1970-01-01
    • 2012-04-19
    相关资源
    最近更新 更多