非聚集覆盖指数栏选择规则

时间:2012-01-11 10:05:39

标签: sql indexing

我有一个包含大约19列的表,其中包含大量合理的数据,主要是使用基于不同where子句的select语句来查询数据。由于主要查询此表以获取数据,因此我考虑根据查询中使用的where子句创建Non Clustered索引。此外,所有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]以及[col_d] - >最后一个SP会使用此索引吗?                                        因为前两列与订单匹配

    另外,我们是否应该继续尝试根据表格中获取SP的过滤器/连接子句定义非群集索引?

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

2 个答案:

答案 0 :(得分:1)

  

[col_a]和[col_b]
  第一个SP是否仍然使用此索引   订单被撤销

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

如果您有索引(col_a, col_b),则可以在指定:

时使用它
  • 只是col_a
  • col_acol_b(订单无关紧要)

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

  

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

是 - 正如我上面提到的,如果使用n个最左边的列,可以考虑索引,所以如果你指定总共三个中的前两个 - 你没事。

警告词:仅仅因为您指定了正确的列并不一定意味着最终会实际使用索引。查询优化器将认为它供使用 - 但如果更方便/更快,它可能仍会采用另一种方式。

答案 1 :(得分:1)

WHERE子句中的顺序与此无关。所以,是的,这两个索引将完美地服务于所有四个例子。

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

您可能会发现,如果您创建的索引非常适合您使用的每个连接,那么您有很多索引。写入表时,这可能会导致性能问题。在这种情况下,您可能会发现一小组索引,这些索引对于您的JOIN和WHERE子句来说并不完美,但是它们足以让您只使用少数几个。这是你需要平衡自己的妥协。


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

这是因为索引的主要特征是记录的顺序。理想的情况是在一个顺序块中(在WHERE子句和JOIN过滤掉它之后)以及对后续JOIN或GROUP BYs友好的顺序中包含所有感兴趣的记录。实际上,您的目标是使数据尽可能少的顺序集群,并尽可能地适合订单。然后让RDBMS优化器完成其余的工作:)