免责声明:我不是 DBA。过去我从这个板上学到了一些我正在构建的东西。
我有一张谷歌分析会话开始时间表。我在每一列上都有一个索引。我想过滤两个日期之间开始的所有会话。下面的屏幕截图显示了查询和索引。
查询运行得很快,但我不相信它使用基于执行计划的索引,这两个都说缺少索引并显示表扫描而不是索引扫描:
为什么?
是不是因为我搜索日期时间的方式?如果不是在日期之间查看,而是将其设置为等于日期,则执行计划会使用索引显示它:
但这不仅仅是这个表或日期时间。这是一个不同的表,在 varchar 列上有一个索引:
对此的一个简单查询也告诉我我缺少索引:
我难住了。
Jos*_*ell 10
如果您希望 SQL Server 对该特定查询使用该索引,则需要包含该session_id列。否则,对于它发现的每一行,它都必须在基表中进行键查找。它会选择对小结果集执行此操作,但是一旦超过一定数量的行(“临界点”),SQL Server 认为仅扫描整个基表会更有效。
您可以使用语法的INCLUDE子句CREATE INDEX来完成此操作:
CREATE NONCLUSTERED INDEX IX_Start_Time
ON GoogleAnalytics.SessionStartTimes (session_start_time)
INCLUDE (session_id);
Run Code Online (Sandbox Code Playgroud)
让我们一步一步地分解正在发生的事情:
session_id每一行的值。session_id不在索引中,所以需要从基表中查找您有多种解决方案:
session_id索引。这不必是键的一部分,它可以是一INCLUDE列。我不建议这样做,因为它会以堆的形式离开表。session_start_time。这意味着所有列都包含在索引中。请记住,聚集索引不是表的额外索引,它是表。无论如何,它通常比堆表更有效。请注意,PK也没有必须聚集键。session_id。然后您的非聚集索引将自动包含session_id(因为那是行定位器)。你可能想让它成为一个 PK,我怀疑无论如何都应该如此。再次,它不具备成为PK。您选择哪个选项取决于通常过滤或分组的列。如果此查询是表上唯一完成的查询,那么您将聚集在session_start_time.
| 归档时间: |
|
| 查看次数: |
444 次 |
| 最近记录: |