Sql server Sql Server-未使用索引

Sql server Sql Server-未使用索引,sql-server,performance,indexing,database-performance,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:表有7

运行以下查询后:

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:表有7000万个条目,这个查询运行大约需要9分钟

编辑1
如果我不在索引中使用选择或筛选列,它还会被使用吗?通常我也会过滤/group by clientId,在整个数据库中大约有300个唯一的和24小时唯一的…

在这种情况下,有两个因素会影响SQL Server选择索引的方式

索引的选择性如何。选择性越高越好。空/非空过滤器通常具有非常低的选择性。 是索引中的所有列,也称为覆盖索引。 在您的示例中,如果索引不能覆盖查询,SQL将不得不根据基表查找其他列值。如果URL/Floordate组合的选择性不够,SQL可能会确定扫描基表比从非聚集索引到基表查找大量行更便宜

在不了解任何其他模式的情况下,我建议使用包含以下列的索引:

floordate, url, hour; include elapsed
日期范围扫描通常比空/非空测试更有选择性。将Floordate移动到前面可能会使此索引更适合此查询。如果SQL确定查询适用于Floordate和URL,则小时列可用于Group By action。由于包含了经过时间,因此该索引可以完全覆盖查询

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


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

列的小时数和时间长度如何,如果这些列未包含在您提到的索引中,则查询将需要在聚集索引中查找以获取这些值。单个列上的索引不会覆盖整个查询时间,并且仍然需要查找已用的列,如果大多数行的url不为NULL,则url上的索引根本没有用处。因此,这一切都取决于floordate>=“2017-05-01”将覆盖多少行引擎估计值,以及聚集索引查找是否优于直接扫描。如果你的统计数据已经过时,这个估计可能会大错特错。在做任何其他事情之前,请尝试更新这些内容。下一个逻辑步骤是在该索引中包含列。您可以用count1替换count*,这可能有助于缩短时间。。您是否可以添加表架构以及@Jeroenmoster说的索引。另外,请查看索引中的列顺序。根据您的查询方式,在没有url的情况下,您的列顺序应该是floordate,然后是url。