Answers:
因此,进入了性能调整和索引策略的艺术领域……
对我来说,修改现有索引定义以包括建议的列似乎是合乎逻辑的
我将以您的报价为基础并编写第三个索引定义:
create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);
那应该是CREATE INDEX
与您引用的语句相对应的语句。
那可能是一个审慎的解决方案,但这取决于。当我说这取决于时,这里有几个例子。
如果您有一个常见的工作负载,主要由以下查询组成:
select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;
那么您的idx_index1
索引将是可靠的。完全狭窄,它是一个索引,它满足其中没有多余数据的查询(如果有的话,也无需考虑聚簇索引定义)。
但是,如果您的工作量主要由以下查询组成:
select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;
这idx_index2
将是明智的,因为这就是所谓的覆盖索引,可避免需要对聚集索引(或对堆的RID查找)进行键查找。该非聚集索引定义将仅包含查询所需的所有数据。
根据您的建议,它非常适合以下查询:
select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;
您的idx_index3
推荐将是满足上述查询搜索条件的覆盖索引。
我要说的是一个孤立的问题,我们无法确切地回答。这完全取决于常见和频繁的工作量。当然,您总是可以定义所有这三个索引来处理每种示例查询类型,但是随之而来的是保持这些索引更新所需的维护(例如:INSERT,UPDATE,DELETE)。那就是索引的开销。
您需要剖析和评估工作负载,并确定在哪些方面优势最大。如果第一个示例查询是目前为止最常见的一次每秒执行数十次,并且不像第三个示例查询那样非常不频繁地进行查询,则使用INCLUDE
非关键列。这完全取决于您的工作量。
如果您了解审慎的索引编制策略,并且了解常见的工作量,则通过同时使用这两种方法,您将能够提出最佳的选择方法。
多一点,关于托马斯回答的含义之一:
他说:
当然,您总是可以定义所有这三个索引来处理每种示例查询类型,但是随之而来的是保持这些索引更新所需的维护(例如:INSERT,UPDATE,DELETE)。那就是索引的开销。
因此,另一个大问题变成了:表多久更新一次?
首先考虑一个不断更新的表的示例,例如ORDERS
反映网站消费者活动的零售表...在那里,您要认真考虑拥有多个索引,因为它们增加了不断更新的工作量,因此不断影响数据库的性能。
在另一方面,考虑到只更新网站安装的一部分表-表更新ONCE对于大多数的价值观,以及很少的附加价值-在那里,更新速度变慢是几乎不考虑。多个索引可能会减慢数据库索引的重建和重组速度,但是只要它们足够快,就可以免费使用:如果多个索引加快了读取速度,那就去吧。
一个中间情况可能是一个表,该表通常仅在一整批过程中在一夜之间进行更新。在那里,来自多个索引的更新速度降低不会影响白天的性能 -它们只会影响(1)运行夜间批维护的时间,(2)任何并发进程的性能以及(3)花费的时间。数据库维护任务,例如索引重组。因此,只要在这三个领域中的进程对您来说运行得足够快,就可以创建加速查询的索引。
嗯...