非聚集覆盖索引列选择规则



我有一个大约有19列的表,其中包含合理的大量数据,主要是使用基于不同where子句的select语句来查询数据。由于查询该表主要是为了获取数据,所以我考虑根据查询中使用的不同where子句创建非聚集索引。此外,所有的get查询都会将表中的所有列作为选择列表的一部分返回。根据以上信息,我有两个选择索引的问题:

  1. 让我们假设我们有以下查询为的SP:

    where [col_a] = {value} and [col_b] = {value}
          [col_b] = {value} and [col_a] = {value}
          [col_a] = {value} and [col_c] = {value} and [col_d] = {value}
          [col_a] = {value} and [col_c] = {value}
    

    我在表上创建了以下非聚集索引作为

    [col_a]和[col_b]-->第一个SP是否仍将此索引用作订单被逆转

    [col_a]和[col_c]和[cl_d]->最后一个SP会使用此索引吗因为前两列与订单匹配

    此外,我们是否应该继续尝试基于表上get SP的filter/join子句来定义非聚集索引?

  2. 由于所有SP中的选择列表都返回完整的列列表,因此我将表中的所有列添加为非聚集索引(覆盖索引)中的包含列,以避免书签查找。这种方法正确吗?既然我们将所有表列存储为索引定义的一部分,那么这种情况下的空间含义是什么?

[col_a]和[col_b]
第一个SP是否仍将此索引用作订单颠倒

是-如果同时指定两个列,并且索引包含这两列作为列列表中的前两列,则可以使用索引,并且顺序并不重要。

如果您有一个索引(col_a, col_b),如果您指定:,则可以使用它

  • col_a
  • col_acol_b(顺序无关)

但它不能用于仅指定col_b(但不指定col_a)的查询。为了考虑使用,必须以任何顺序使用/定义最左边的n列(n>=1)。

[col_a]和[col_c]以及[col_d]
最后一个SP会使用此索引吗因为前两列与顺序匹配

是的,正如我上面提到的,如果使用最左边的n列,则可以考虑索引,所以如果您指定了总共三列中的前两列,那么就可以了。

警告:仅仅因为指定了正确的列并不一定意味着索引最终会被使用。查询优化器将考虑使用它,但如果更方便/更快,它可能仍然会走另一条路。

WHERE子句中的排序与此处无关。因此,是的,这两个索引将很好地服务于所有四个示例。

至于帮助JOIN的索引,是的,通常有建议。

您可能会发现,如果您创建的索引非常适合您使用的每个联接,那么您就有很多索引。这可能会导致写入表时出现性能问题。在这种情况下,您可能会发现一小部分索引不适合您的JOIN和WHERE子句,但它们足够好,您只需使用这几部分就可以管理它们。这是一种妥协,你需要平衡自己。


最后,请注意,一些RDBMS可以使用索引合并。这可能意味着多个简单或更简单的指数几乎与一个复合/覆盖指数一样好。但在大多数情况下,在考虑索引内容时,确实需要同时考虑WHERE子句和JOIN。

这是因为索引的主要特征是记录的顺序。理想的场景是将所有感兴趣的记录放在一个连续的块中(在WHERE子句和JOIN过滤掉它之后),并按照对后续JOIN或GROUP BYs友好的顺序。事实上,您的目标是使数据尽可能少地按顺序排列,并尽可能符合顺序。然后让RDBMS优化器完成剩下的工作:)

最新更新