Sql Server - 未使用索引

时间:2017-05-24 12:33:20

标签: sql-server performance indexing database-performance

运行以下查询后:

SELECT [hour], count(*) as hits, avg(elapsed)
FROM myTable
WHERE [url] IS NOT NULL and floordate >= '2017-05-01'
group by [hour]

执行计划基本上是PK上的聚集索引扫描(int,自动增量,97%的工作)

事情是:URL有一个索引(常规索引,因为我总是在搜索完全匹配),floordate也有一个索引......

为什么不使用它们?我怎样才能加快这个问题?

PS:表长70M项,此查询大约需要9分钟才能运行

编辑1
如果我不在我的索引上使用(选择或过滤)一列,它还会被使用吗?通常我也会过滤/分组clientId(数据库中大约300个唯一的)和hour(24个唯一的)......

1 个答案:

答案 0 :(得分:1)

在这种情况下,有两件事会影响SQL Server选择索引的方式。

  1. 索引的选择性如何。选择性越高越好。 NULL / NOT NULL过滤器通常具有非常低的选择性。
  2. 是索引中的所有列,也称为覆盖索引。
  3. 在您的示例中,如果索引无法覆盖查询,则SQL必须针对基表查找其他列值。如果您的URL / Floordate组合没有足够的选择性,SQL可能会确定扫描基表的成本更低,而不是从非聚集索引到基表的大量行进行昂贵的查找。

    在不了解您的架构的任何其他内容的情况下,我建议使用以下列的索引:

    floordate, url, hour; include elapsed
    

    日期范围扫描通常比NULL / NOT NULL测试更具选择性。将Floordate移动到前面可能会使此索引更适合此查询。如果SQL确定查询适用于Floordate和URL,则“小时”列可用于“分组依据”操作。由于包含了Elapsed,因此该索引可以完全覆盖查询。

    您可以在一小时后包含ClientID,看看这是否也有助于您的其他查询。

    只要索引包含要解析查询的所有列,即使没有需要过滤,也可以使用它。一般来说,非聚集索引比基表更瘦,比扫描全宽基表需要更少的IO。

相关问题