我有一个包含大约19列的表,其中包含大量合理的数据,主要是使用基于不同where子句的select语句来查询数据。由于主要查询此表以获取数据,因此我考虑根据查询中使用的where子句创建Non Clustered索引。此外,所有get查询都会返回表中的所有列,作为选择列表的一部分。根据上述信息,我有两个选择索引的问题:
让我们假设我们有以下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的过滤器/连接子句定义非群集索引?
由于所有SP中的选择列表都返回整个列列表,因此我将表的所有列添加为非聚簇索引(覆盖索引)中的包含列,以避免书签查找。这种方法是否正确?在这种情况下,由于我们将所有表列存储为索引定义的一部分,所以空间含义是什么?
答案 0 :(得分:1)
[col_a]和[col_b]
第一个SP是否仍然使用此索引 订单被撤销
是 - 如果指定两个列,并且索引包含这两列作为其列表中的前两列,则可以使用索引,并且顺序并不重要。< / p>
如果您有索引(col_a, col_b)
,则可以在指定:
col_a
col_a
和col_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优化器完成其余的工作:)