Sql 服务器 - 未使用索引
Sql Server - Index not being used
在 运行 宁以下查询之后:
SELECT [hour], count(*) as hits, avg(elapsed)
FROM myTable
WHERE [url] IS NOT NULL and floordate >= '2017-05-01'
group by [hour]
执行计划基本上是PK上的clustered Index Scan(int,自增,97%的工作)
问题是:URL
上有一个索引(常规索引,因为我一直在搜索完全匹配),floordate
也有一个索引...
为什么它们没有被使用?我怎样才能加快这个查询?
PS:table 有 7000 万个项目,此查询需要大约 9 分钟才能到达 运行
编辑 1
如果我不使用(select 或过滤)我的索引中的列,它还会被使用吗?通常我也 filter-for/group-by clientId
(整个数据库中大约 300 个唯一)和 hour
(24 个唯一)...
在这种情况下,有两件事会影响 SQL 服务器选择索引的方式。
- 索引的选择性如何。选择性越高越好。 NULL/NOT NULL 过滤器的选择性通常很低。
- 是索引中的所有列,也称为覆盖索引。
在您的示例中,如果索引无法覆盖查询,SQL 将不得不根据基础 table 查找其他列值。如果您的 URL/Floordate 组合选择性不够,SQL 可能会确定扫描基础 table 比从非聚集索引到基础 [=36] 进行昂贵的查找更便宜=] 对于大量行。
在不了解您的架构的任何其他信息的情况下,我推荐一个包含以下列的索引:
floordate, url, hour; include elapsed
日期范围扫描通常比 NULL/NOT NULL 测试更具选择性。将 Floordate 移到前面可能会使该索引更适合该查询。如果 SQL 确定查询适用于 Floordate 和 URL,则 Hour 列可用于 Group By 操作。由于包含了Elapsed,这个索引可以完全覆盖查询。
您可以在下班后加入 ClientID,看看是否对您的其他查询也有帮助。
只要索引包含解析查询的所有列,它就是可用的候选者,即使不需要过滤也是如此。一般来说,非聚集索引比基 table 更瘦,比扫描全宽度基 table.
需要更少的 IO
在 运行 宁以下查询之后:
SELECT [hour], count(*) as hits, avg(elapsed)
FROM myTable
WHERE [url] IS NOT NULL and floordate >= '2017-05-01'
group by [hour]
执行计划基本上是PK上的clustered Index Scan(int,自增,97%的工作)
问题是:URL
上有一个索引(常规索引,因为我一直在搜索完全匹配),floordate
也有一个索引...
为什么它们没有被使用?我怎样才能加快这个查询?
PS:table 有 7000 万个项目,此查询需要大约 9 分钟才能到达 运行
编辑 1
如果我不使用(select 或过滤)我的索引中的列,它还会被使用吗?通常我也 filter-for/group-by clientId
(整个数据库中大约 300 个唯一)和 hour
(24 个唯一)...
在这种情况下,有两件事会影响 SQL 服务器选择索引的方式。
- 索引的选择性如何。选择性越高越好。 NULL/NOT NULL 过滤器的选择性通常很低。
- 是索引中的所有列,也称为覆盖索引。
在您的示例中,如果索引无法覆盖查询,SQL 将不得不根据基础 table 查找其他列值。如果您的 URL/Floordate 组合选择性不够,SQL 可能会确定扫描基础 table 比从非聚集索引到基础 [=36] 进行昂贵的查找更便宜=] 对于大量行。
在不了解您的架构的任何其他信息的情况下,我推荐一个包含以下列的索引:
floordate, url, hour; include elapsed
日期范围扫描通常比 NULL/NOT NULL 测试更具选择性。将 Floordate 移到前面可能会使该索引更适合该查询。如果 SQL 确定查询适用于 Floordate 和 URL,则 Hour 列可用于 Group By 操作。由于包含了Elapsed,这个索引可以完全覆盖查询。
您可以在下班后加入 ClientID,看看是否对您的其他查询也有帮助。
只要索引包含解析查询的所有列,它就是可用的候选者,即使不需要过滤也是如此。一般来说,非聚集索引比基 table 更瘦,比扫描全宽度基 table.
需要更少的 IO