我有一个包含 1500 万行的表,它是一个带有 12 个子表的父表。
即使对于简单的计数查询,也需要几个小时才能完成。
select count(1) from table
where col_filter >= 'number'
table
包含 40 列并且col_filter
具有varchar
数据类型。col_filter
未编入索引。
问题:
- 我应该检查什么来发现我的桌子设置的潜在问题?
- 我正在使用 Microsoft SQL Server Management Studio 18,是否有任何工具可以用来了解并获得一些优化性能的建议?
- 如果索引是解决方案,是否可以计算索引创建将占用多少额外空间?
更新1:
该表是其他数据获取查询的一部分,其中包含,cte
然后inner joins
用作cte
执行分组操作的基表,我在帖子中发布的表是cte内的基表,因为即使是计数也需要很长时间,我认为这将是调试的良好开始。这是完整的查询,其中包含估计 执行计划和实际 执行计划,运行时间超过 18 小时。
等待信息select count(1) from table where col_filter >= 'number'
:
(35ms)PAGEIOLATCH_SH:dev-db:1(*)
(26ms)PAGEIOLATCH_SH:dev-db:1(*)
(86ms)PAGEIOLATCH_SH:dev-db:1(*)
(9ms)PAGEIOLATCH_SH:dev-db:1(*)
这是实际的执行计划
任何建议都将非常感激。
正如您已经被建议的那样(在您的两篇帖子之间),索引
(col_filter)
将有助于您提供的示例查询。如果您只运行这样的聚合查询,那么非聚集列存储索引可能是最好的选择,这样您就可以获得列压缩(这将最大限度地减少索引的磁盘空间开销)并提高批处理模式操作的性能。除此之外,正如 Martin 在您的另一篇文章中指出的那样,即使扫描 150 万行的整个表,4 小时仍然是不寻常的。但由于您位于云中,因此有很多因素可能会成为查询的瓶颈。没有看到实际的执行计划就很难说。您还可以
sp_WhoIsActive
在等待查询完成执行时在单独的查询窗口中运行,以查看它正在等待什么(等待类型)以及是否有任何阻塞进程。了解这一点也会很有帮助。从索引开始,看看这是否会带来显着的改进(即您的示例查询不应超过一分钟 - 老实说,这很慢)。如果问题仍然存在,请使用表的定义和慢速查询的实际执行计划更新您的帖子,您可以将其上传到“粘贴计划”,然后链接到您的帖子中。
你可以尝试这个:
在 Oracle 中我们不使用
Count
- 而是检查查询是否返回任何行。