在此之前,我已经在特定索引上完成了此操作,以帮助经常运行的繁重查询。实际上,他们所做的就是创建了多个聚簇索引:当使用这些索引中的任何一个来查找行时,不需要额外的工作来查找真实聚簇索引(如果没有真实聚簇索引,则查找堆)中的其余数据。 。
这是明智的策略吗?
对于某些需要支持某些查询模式的索引,肯定可以。
但是要对所有索引执行此操作,我肯定会说不。
在实际不需要的地方做的工作将浪费很多空间,并且会大大降低插入/更新的速度。它可能会减慢尽可能多的读取查询的速度,因为每个索引页面保存的记录较少,因此任何需要引用索引块进行过滤但不使用所有其他列的查询都必须访问更多页面。这将使数据库更加耗费内存:这些页面将需要加载到缓冲池中,如果内存不足,则有可能弹出其他有用的页面。如果对那些索引使用压缩以减轻对存储和内存要求的影响,那么它将向CPU施加额外的负担。
因为访问是通过默认(但并非总是)通过ORM检索所有列的
这是在ORM(或仅是幼稚的ORM)的优化使用不佳的情况下出现的常见模式,在这种情况下,我已经看到SQL Server的索引顾问(和类似的第三方工具)建议包含许多INCLUDE
d列的索引,因此我同意您的观点。建议这就是为什么以这种方式创建索引的原因。
但是,尽管这可能会使所有这些查询稍快一些,而其中一些查询却显着更快,但我怀疑在许多情况下,这样做的好处是如此之小,以至于不值得您使用通用工作集,磁盘空间和磁盘和内存之间的IO。
还请记住,ORM可能不会选择查询所涉及的所有表的所有列,因此,好处可能仅适用于当前请求的主要目标,并且当使用其他对象进行过滤时,较大的索引可能会对查询造成不利影响但不返回数据(SELECT * FROM table1 WHERE id IN (SELECT someID FROM table2 WHERE someColumn='DesiredValue')
也许)。
使用多余空间的另一个考虑因素(尤其是在数据较大的情况下)将对您的备份策略产生影响:这些备份的存储和传输成本,潜在的还原时间等。
我们应该为两者之间的任何差异做好准备吗?
通常,我认为每种情况下这里的注意事项都是相同的,尽管在Azure中您可以调整服务层,从而可以更直接地看出由大索引施加的任何额外的内存/ IO成本,因此比起与之相比,基础架构成本更容易具有相对固定的一组硬件资源。如果使用标准/高级层而不是基于vcore的定价,那么标准中的IO成本将对您造成更大的影响,因为高级服务每DTU包含的IO明显更多。如果在Azure中使用多区域备份或冗余或其他非本地功能,则不必要的宽索引占用的额外空间可能会带来带宽成本。
SELECT
没有指定ORDER BY
开始返回与以前相同的行,但是具有不同的任意顺序。