我有一张大约有 19 列的表,其中包含相当大量的数据,主要使用基于不同 where 子句的选择语句进行查询以检索数据。由于该表主要用于查询以获取数据,因此我考虑根据查询中使用的不同 where 子句创建非聚集索引。此外,所有 get 查询都会将表中的所有列作为选择列表的一部分返回。根据以上信息,我对选择索引有两个问题:
- 假设我们有以下 SP,其查询如下:
其中 [col_a] = {值} 且 [col_b] = {值}
[col_b] = {值} 且 [col_a] = {值}
[col_a] = {值} 且 [col_c] = {值} 且 [col_d] = {值}
[col_a] = {值} 且 [col_c] = {值}
我在表上创建了以下非聚集索引
[col_a] 和 [col_b] -->由于订单被逆转,第一个 SP 是否仍会使用此索引
[col_a] 和 [col_c] 和 [col_d] -->最后一个 SP 是否会使用此索引,因为前两列与顺序匹配
另外,我们是否应该继续尝试根据表上的获取 SP 的过滤/连接子句来定义非聚集索引?
- 由于所有 SP 中的选择列表都返回整个列表,因此我将表的所有列添加为非聚集索引(覆盖索引)中的包含列,以避免书签查找。这种方法正确吗?由于我们将所有表列存储为索引定义的一部分,因此在这种情况下对空间的影响是什么?
答案1
1:如果在查询中(在 WHERE 子句或 JOIN 条件中)使用了两列,则索引列的顺序无关紧要。
2:可以使用部分索引从左边开始计算:在搜索时可以使用(a,b)A独自的。
由于 A 列在所有 4 个查询中都有使用,因此我建议您始终将其包含在索引中。
接下来,A 列和 C 列也一起使用,这样就得到了第二个索引:
IX_1 (col_a,col_b)
IX_2 (col_a,col_c,col_d)
应该会给你最佳的表现。
我假设其中有一列是 PK - 如果不是,则需要创建一个。
包含所有列的覆盖索引是一个非常糟糕的想法,因为 PK 查找比维护表的 2 个完整数据副本所产生的开销要小得多。
当然,包含所有列的覆盖索引是整个表的副本。