【问题标题】:Should I have a Primary Key on User Defined Table Types?我应该在用户定义的表类型上有一个主键吗?
【发布时间】:2014-02-27 11:16:18
【问题描述】:

首先,我了解主键在 SQL 表或任何数据库中的作用。

但是,当涉及到用户定义的表类型时,我发现自己无法理解为什么要创建主键。根据我的经验,我没有发现它们对性能有任何好处,但我怀疑我的发现可能来自我对它们的一般用法和有限的经验,而不是更有经验的观点。

例如,我通常将表值参数用于插入/更新过程,或者传递用于创建选择查询的值数组。我没有发现它们对性能有任何好处,而且如果有什么我经历过的小幅性能下降(但我们说的是最多 10 毫秒,所以它可以忽略不计)。

我应该透露,其中传递的任何数据都已被非常小心地清理/排序,因此我可能没有看到任何好处,但我无法轻易知道。

因此,问题又是,我应该在我的用户定义表类型上有一个主键,还是它只是不那么重要?

抱歉,如果这是重复的。我进行了大量搜索,但我可能使用了错误的关键字组合。

我们将一如既往地感谢您的见解。

【问题讨论】:

  • 您的性能下降很小,因为必须构建聚集索引。如果数据是预先排序的,并且您不会对数据执行选择性查询,那么索引只是浪费资源。如果您不想对集合施加新顺序或重复调用集合上的一些选择性查询,这将受益于索引,并且如果集合足够大,那么值得创建聚集索引和可能的其他非成簇的缺陷。
  • @Jodrell,谢谢,这很有意义。出于某种疯狂的原因,我没有考虑构建聚集索引的开销!!!很高兴知道我对预购数据的假设是准确的。

标签: database sql-server-2012 table-valued-parameters


【解决方案1】:

其实,我对同一件事感到好奇,只是从不同的角度...

我们有一个动态查询,该查询是根据用户输入组合而成的,结果类似于

"SELECT A.* 
FROM A
<some joins, etc>
WHERE A.ID IN ('" + String.Join("','", List<UserInputs>) + "')"

我想用 tvp 关闭 sql 注入孔,但查询性能完全下降(慢了几个数量级)。

使用文字的计划开始于对 id 列进行漂亮、干净的索引扫描,并且非常快。

在进入选择性部分之前,TVP 的计划与连接到 tvp 并实现整个表变得复杂。

我想知道将主键放在 tvp 类型上是否可以让优化器生成更好的计划。

【讨论】:

    【解决方案2】:

    如果您传递的数组是一个 id 数组,可以直接在与其他表连接时匹配,那么拥有一个聚集的主键是很有意义的。

    为避免在插入之前花时间订购数据,您应该已经在应用程序端订购了它。

    在这种情况下,我经历了大约 400 毫秒的增益。

    必须逐案评估。

    【讨论】:

      【解决方案3】:

      您可以在用户定义的表类型上创建主键,从而形成聚集索引。但不能在用户定义的表类型上创建非聚集索引..

      有关您的信息,请参阅以下页面

      http://technet.microsoft.com/en-us/library/bb522526(v=sql.105).aspx

      【讨论】:

      • 谢谢。我花了很多时间事先查看该特定页面。虽然我明白所有这些,但在这种情况下,它并不能真正回答我遇到的我应该/不应该的难题。
      猜你喜欢
      • 2011-12-22
      • 2010-10-24
      • 1970-01-01
      • 2016-06-30
      • 2016-04-23
      • 2023-04-07
      • 2019-10-30
      • 1970-01-01
      相关资源
      最近更新 更多