【问题标题】:Using Primary Key on Table Variable to improve seek performance在表变量上使用主键来提高查找性能
【发布时间】:2016-03-01 09:33:35
【问题描述】:

我在我的 SP 中使用了这个表变量:

DECLARE @t TABLE(ID uniqueidentifier)

然后我在其中插入一些数据(我以后使用):

INSERT INTO @t(ID)
SELECT ID FROM Categories WHERE ...

后来我有几个SELECTUPDATE 基于@t ID,例如:

SELECT * FROM Categories A INNER JOIN @t T ON A.ID = T.ID

etc..

我应该声明ID uniqueidentifier PRIMARY KEY 以增加SELECT / UPDATE 语句的持久性吗? 如果是,它应该是集群还是非集群? 在我的情况下,建议的选项是什么?

编辑:我在数据库中的所有表都有 uniqueidentifier (ID) 列作为主键 NONCLUSTERED

EDIT2 : 奇怪的是(或没有)当我尝试在表变量上使用 PRIMARY KEY NONCLUSTERED 时,当使用 join SELECT 我在执行计划中看到有一个 Table Scan@t。但是当我省略NONCLUSTERED 时,会有一个Clustered Index Scan

【问题讨论】:

  • 那么,您数据库中的所有表都有一个 GUID 列作为主键(和聚集索引)?
  • 我之前曾多次问过自己这个问题,我发现(速度测试)答案取决于许多因素,包括所涉及的表的大小、所涉及的其他表的结构(被索引的连接列)和其他因素。我非常建议您在使用和不使用 PK 的情况下进行这些速度测试,并尝试使用 @Jaco 建议的临时表。然而,我永远不敢回答这个问题,因为这完全取决于:dba.stackexchange.com/questions/16385/…
  • @IvanStarostin,我在数据库中的表有 GUID 列作为主键 NONCLUSTERED
  • @zig,@t 有多大,计划中使用了什么连接运算符:循环/哈希?你最好在你的问题中发布实际的执行计划。
  • @Ivan, @t 可能有 1 到 100 条记录。我对执行计划的编辑不准确。似乎只有当我向@t(ID 除外)添加更多列时,NONCLUSTERED 才没有效果,或者我可能读错了计划......

标签: sql-server primary-key table-variable


【解决方案1】:

如果您担心性能,您可能不应该使用表变量,而是使用临时表。表变量的问题是引用它的语句在表为空时编译,因此查询优化器总是假设只有一行。当表变量填充更多行时,这可能会导致性能欠佳。

关于主键,将主键设为聚簇存在一些缺点,因为它会导致表按索引进行物理排序。在查询数据时,这种排序操作的开销可能会超过性能优势。一般来说,最好添加一个非聚集索引,但是,与往常一样,这将取决于您的特定问题,并且您必须测试不同的实现。

【讨论】:

    猜你喜欢
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    相关资源
    最近更新 更多