Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL Server中使用顺序Guid作为主键是否会导致大数据的低性能?_Sql_.net_Database Performance_Guid_Sqlperformance - Fatal编程技术网

在SQL Server中使用顺序Guid作为主键是否会导致大数据的低性能?

在SQL Server中使用顺序Guid作为主键是否会导致大数据的低性能?,sql,.net,database-performance,guid,sqlperformance,Sql,.net,Database Performance,Guid,Sqlperformance,我使用过的最大的数据库是SQL Server数据库,其中一个表包含200000行。我使用Guid作为数据库中的主键,而不是顺序Guid。我在该系统中没有遇到性能问题,该系统中有大约30个并发用户 最近,我设计并开发了一个企业应用程序开发框架。为了利用“工作单元”模式,我使用了一个顺序guid作为主键,以便对记录进行物理排序。由于我对大型数据库的经验仅限于我刚才提到的,我有一个严重的问题,如果我要使用这个框架为一个拥有1000个并发用户的大型组织开发一个企业应用程序,它将使用顺序guid作为主键保

我使用过的最大的数据库是SQL Server数据库,其中一个表包含200000行。我使用
Guid
作为数据库中的主键,而不是顺序Guid。我在该系统中没有遇到性能问题,该系统中有大约30个并发用户

最近,我设计并开发了一个企业应用程序开发框架。为了利用“工作单元”模式,我使用了一个顺序guid作为主键,以便对记录进行物理排序。由于我对大型数据库的经验仅限于我刚才提到的,我有一个严重的问题,如果我要使用这个框架为一个拥有1000个并发用户的大型组织开发一个企业应用程序,它将使用顺序guid作为主键保存数百万条数据记录,这会导致性能问题吗

如果是,到什么程度?如果是的话,可以通过改进数据库服务器硬件(处理器和RAM)来解决这个问题,然后再提高到什么程度


提前感谢您分享您的经验和知识

GUID
似乎是您主键的自然选择-如果您确实需要,您可能会争辩将其用作表的主键。我强烈建议不要使用
GUID
列作为集群键,SQL Server默认情况下会这样做,除非您明确告诉它不要这样做

您确实需要将两个问题分开:

  • 主键是一个逻辑结构-唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,真的-一个
    INT
    ,一个
    GUID
    ,一个字符串-选择对您的场景最有意义的内容

  • 聚集键(表中定义“聚集索引”的一列或多列)-这是一个与物理存储相关的东西,在这里,一个小的、稳定的、不断增加的数据类型是最佳选择-
    INT
    BIGINT
    ,作为默认选项

  • 默认情况下,SQL Server表上的主键也用作集群键-但不需要这样!我个人看到,将以前基于GUID的主键/聚集键拆分为两个单独的键时,性能有了巨大的提高—在
    GUID
    上的主键(逻辑)键和在单独的
    INT IDENTITY(1,1)
    列上的聚集(排序)键

    正如“索引女王”和其他人多次指出的那样,
    GUID
    作为群集键不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片,并导致总体性能不佳

    是的,我知道-在SQL Server 2005和更高版本中有
    newsequentialid()
    ,但即使是这样也不是真正的完全顺序的,因此也会遇到与
    GUID
    相同的问题-只是不太明显而已

    然后还有另一个需要考虑的问题:表上的集群键也将添加到表中每个非集群索引的每个条目中——因此您确实希望确保它尽可能小。通常情况下,一个具有20多亿行的
    INT
    对于绝大多数表来说应该足够了——与作为集群键的
    GUID
    相比,您可以在磁盘和服务器内存中节省数百兆的存储空间

    快速计算-使用
    INT
    GUID
    作为主键和群集键:

    • 包含1'000'000行的基表(3.8MB与15.26MB)
    • 6个非聚集索引(22.89MB对91.55MB)
    总计:25MB对106MB-这只是在一张桌子上

    是的,表或索引的大小越大,自动意味着需要从磁盘加载、保存在内存中、传输到客户端的数据页越多,所有这些都会对性能产生负面影响影响的程度实际上取决于数据库设计和数据分布的许多因素,因此任何广义预测几乎都是不可能的

    更多值得思考的东西——金伯利·特里普的优秀作品——读一读,再读一读,消化它!这是SQL Server索引的福音,真的


    顺序GUID与“常规”GUID的问题在以下情况下出现:

    • GUID列是主索引或聚集索引(特别是索引中唯一的键)的一部分
    • 您的数据库上有“很多”插入项
    对于聚集索引,SQL Server会“按顺序”向表中添加新记录。因此,较大的值位于表的“末尾”——在本例中,位于最后一个数据页。这对于标识列很方便,因为它们保证比以前的任何值都大。根据定义,最后一个数据页不是零碎的

    GUID没有此属性。它们最终被插入“中间”,导致碎片化

    你为什么不认为这是个问题?可能有多种原因:

    • 您的应用程序没有执行很多插入操作
    • 您正在定期对表进行碎片整理
    • 这张桌子太小了,这几乎无关紧要
    至于后一点,如果记录足够小,那么每页上可能会出现一千多条记录。对于200页的数据,碎片可能不是一个重要问题

    对于30个并发用户,您可能没有事务重叠。如果每个用户每分钟修改一次数据库,那么您就有2秒钟的时间来完成一个事务——通常足够长的时间

    尽管如此,我还是建议使用seque