C# 在SQL Server中使用GUID对性能的影响

C# 在SQL Server中使用GUID对性能的影响,c#,sql,sql-server,entity-framework,C#,Sql,Sql Server,Entity Framework,在询问之前我已经尝试过搜索这个,但是我发现的每个结果都提到guid是一个PK,而这里不是这样 我有一个数据库,它使用INT作为所有表的主键。但是,数据是通过API调用访问的,并且要求在任何API中都不返回或使用INT值。因此,我考虑在包含GUID的表上增加一列 现在我的问题是,如果我为GUID列编制索引,这会对性能产生什么样的影响?它是正面的还是负面的?请记住GUID不是PK或FK。这应该可以。当然,任何索引和任何列占用更多空间都会产生正常影响。因此,数据修改会稍微慢一点。与整数相比,使用GUI

在询问之前我已经尝试过搜索这个,但是我发现的每个结果都提到guid是一个PK,而这里不是这样

我有一个数据库,它使用INT作为所有表的主键。但是,数据是通过API调用访问的,并且要求在任何API中都不返回或使用INT值。因此,我考虑在包含GUID的表上增加一列


现在我的问题是,如果我为GUID列编制索引,这会对性能产生什么样的影响?它是正面的还是负面的?请记住GUID不是PK或FK。

这应该可以。当然,任何索引和任何列占用更多空间都会产生正常影响。因此,数据修改会稍微慢一点。与整数相比,使用GUID查找记录的速度稍慢。除非您有一个非常高吞吐量的应用程序,否则这些可能不是重要的考虑因素

一个关键点是GUID列不应进行集群。这非常重要,因为guid是随机的,但主键是有序的。如果将GUID用于聚集索引,则几乎每次插入都会在两个现有记录之间进行,这需要大量数据移动。相反,作为聚集索引的标识列总是插入到数据的末尾


我猜您在guid上的引用已经讨论了这个问题。

我认为您的思路是正确的,但不要从我这里拿走它

在Kimberly Tripp的一篇文章的评论部分,她回应了一条与您的立场相反的评论,她不同意并支持您提出的相同解决方案(带有聚集int/bigint主键的非聚集索引guid)

赫尔曼:

如果GUID是被建模实体的内在标识符(即由selects使用),那么毫无疑问,它应该是集群主键。原因是,添加代理标识键(int或bigint)并将GUID主键降级到具有索引/唯一约束的列需要维护2个索引,根据我的经验,这会降低2倍的速度


金伯利Tripp

嘿,赫尔曼,事实上,我不同意。对于使用非聚集索引的基于点的查询,不会添加大量昂贵的IOs。而且,维护高度碎片化的非聚集索引要比维护高度碎片化的聚集索引便宜得多。此外,GUID可能会使非聚集索引变得不必要的宽—使它们占用更多的日志空间、磁盘空间、缓存以及插入和访问时间(特别是在较大的查询/联接中)

因此,虽然您可能不觉得任意/代理项键有用(因为您从未直接查询过它),但通过非聚集索引间接使用它可能会非常高效。这里肯定有“视情况而定”的元素,但如果你只有几个非聚集索引,那么它可能比负的更有益,而且通常是显著的

干杯,
kt~


如果在此列上创建索引,则在基于GUID的任何搜索中都会获得更好的性能;因为这就是索引的作用。与每个索引一样,添加新索引将在insert/update/delete中增加更多工作,而对于select操作,只有在该列上搜索时才有用。如果在guid上放置索引,则性能影响将是索引查找,然后是gets上的键查找,而不是简单的键查找,加上维护额外索引的开销(可能仅在插入/删除时,因为您不太可能需要更改现有行的guid?)。这将是一个负面影响,但不一定显著。您需要在具有代表性的数据量上测试它,并确定性能是否适合您的用例。这迫使您每行有两个唯一的值,这是对资源的浪费。在API中不使用PK但GUID正常的原因是什么?@SeanLange。当律师掌握了隐私法时,最令人惊奇的事情就会发生。我对内部标识符也有类似的要求。此外,一些公司回避返回自动递增的值,因为它可能会无意中释放其他信息,例如他们有多少客户。SQL Server中的主键不需要群集(排序)。使用顺序GUID如何?Erik:主键不需要群集,但是它们是有序的——所有索引都是有序的。@Evk,使用顺序guid,您会失去使用guid的一个巨大好处。生成的guid本质上是唯一的,这有助于关联数据、合并数据库等。与顺序键不同,guid即使在应用程序的不同实例中也会有所不同,无论是横向扩展、单独的地理实例还是不同的环境(prod、test等)我还发现,在必须回滚数据库和恢复备份后创建的数据时,guid非常方便。