我正在尝试调整一个存储过程,它有一个用于匹配的临时表(仅检索,没有更新或插入)。我们正在考虑将聚集键应用于临时表。我们也在考虑应用主键(集群)。
除了主键的唯一/非空约束之外,就在临时表中查找值而言,聚集索引和主键之间在性能方面是否存在任何差异?
谢谢。
小智 7
聚集索引将决定表页中数据的顺序。当您的临时表最初被填充时,插入的数据将被排序,或者,如果您正在执行多次插入以填充,您可能最终会出现一些页面碎片,因为页面必须拆分以容纳正在写入的额外数据。
假设您的临时表填充在单个插入中,并且您没有页面碎片,下一个可能会或可能不会影响您的性能的问题是 4 字节“唯一标识符”的存在。由于聚集键用作指向表中每一行的指针,因此它必须是唯一的。因此,如果您使用的是非唯一聚集索引,则每个非聚集索引(以及您的聚集索引)都将比您定义的宽 4 个字节,这将影响执行查询所需的页面密度和 IO。这可能只会产生很小的影响,因为 uniquifier 只会添加到重复项中。
您需要考虑的另一个因素是,您如何加入此临时表。SQL Server 支持 3 个物理连接运算符;合并、循环和哈希。在许多情况下,合并可以产生最佳性能。
与总成本可能与输入表中行数的乘积成正比的嵌套循环连接不同,使用合并连接每个表最多读取一次,总成本与行数的总和成正比在输入中。因此,对于较大的输入,合并连接通常是更好的选择。
除非连接的两个数据集都按连接条件排序,否则 SQL 不太可能选择合并运算符。当然,还有其他因素,但如果您可以针对特定的、常见的使用模式优化您的表,那就更好了。
要考虑的第二件事是您要放置在该表上的任何其他索引,因为每个非聚集索引都将包含指定的键(按指定的顺序)和指向聚集索引的指针,以便于查找和检索未涵盖的任何字段通过索引。同样,窄聚集键将在非聚集索引中产生更好的密度,从而为索引扫描和查找提供更好的 I/O 性能。如果您的非聚集索引需要对聚集索引进行多次查找,请考虑在索引中包含这些列(为了减少查找而牺牲页面密度)或考虑根据该标准进行聚集(如果这是您的主要使用模式)
引导我在唯一(或非唯一聚集索引)上使用主键的最大因素是能够在 create table 语句中创建内联索引。从历史上看,我发现优化器不太适合使用我在 create table 语句之后在存储过程中创建的索引。使用 create table 语句内联创建主键更容易。我不确定是否可以使用非约束索引来做到这一点,但您可以创建一个唯一的内联聚集索引。