运行以下查询后:
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个唯一的)......
答案 0 :(得分:1)
在这种情况下,有两件事会影响SQL Server选择索引的方式。
在您的示例中,如果索引无法覆盖查询,则SQL必须针对基表查找其他列值。如果您的URL / Floordate组合没有足够的选择性,SQL可能会确定扫描基表的成本更低,而不是从非聚集索引到基表的大量行进行昂贵的查找。
在不了解您的架构的任何其他内容的情况下,我建议使用以下列的索引:
floordate, url, hour; include elapsed
日期范围扫描通常比NULL / NOT NULL测试更具选择性。将Floordate移动到前面可能会使此索引更适合此查询。如果SQL确定查询适用于Floordate和URL,则“小时”列可用于“分组依据”操作。由于包含了Elapsed,因此该索引可以完全覆盖查询。
您可以在一小时后包含ClientID,看看这是否也有助于您的其他查询。
只要索引包含要解析查询的所有列,即使没有需要过滤,也可以使用它。一般来说,非聚集索引比基表更瘦,比扫描全宽基表需要更少的IO。