Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.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 事务级别、nolock/readpast和并发_Sql Server_Optimization_Concurrency_Transactions_Locking - Fatal编程技术网

Sql server 事务级别、nolock/readpast和并发

Sql server 事务级别、nolock/readpast和并发,sql-server,optimization,concurrency,transactions,locking,Sql Server,Optimization,Concurrency,Transactions,Locking,我们有一个系统,它可以同时插入来自多个站点的大量数据,同时还公开了一个数据查询接口。架构如下所示(很抱歉格式不好): 数据插入是在“同步”中完成的,并且是这样的(我们只向系统中插入数据,从不更新) 查询是这样的(对于给定的站点,测量时间和数据类型) 我的问题是,我们如何将INSERT上的事务级别与查询上的NOLOCK/READPAST提示结合起来,以便: 我们在支持插入的同时最大限度地提高了系统的并发性(我们需要存储大量数据,每秒存储2000多条记录) 查询仅从“提交的”同步返回数据(我们不希望

我们有一个系统,它可以同时插入来自多个站点的大量数据,同时还公开了一个数据查询接口。架构如下所示(很抱歉格式不好):

数据插入是在“同步”中完成的,并且是这样的(我们只向系统中插入数据,从不更新)

查询是这样的(对于给定的站点,测量时间和数据类型)

我的问题是,我们如何将INSERT上的事务级别与查询上的NOLOCK/READPAST提示结合起来,以便:

  • 我们在支持插入的同时最大限度地提高了系统的并发性(我们需要存储大量数据,每秒存储2000多条记录)
  • 查询仅从“提交的”同步返回数据(我们不希望结果集具有半插入的同步或由于锁跳过而具有某些跳过项的同步)
  • 我们不关心查询中是否包含“最新”的数据,我们更关心的是一致性和响应性,而不是“实时”和最新的数据
  • 这可能是非常矛盾的目标,可能需要高事务隔离级别,但我对所有技巧和优化感兴趣,以实现插入和选择的高响应性。如果需要更多的细节来进行更多的调整和技巧,我很乐意详细说明

    更新:只是为以后的回复添加更多信息。我们最初在存储容量超过5 TB的SAN网络上运行SQL Server 2005(可能在六个月内运行2008)。我不确定SAn设置为哪种RAID,也不确定我们有多少可用磁盘

  • 您将使用哪种类型的磁盘系统?如果您有一个大的条带化RAID阵列,那么写操作应该表现良好。如果您可以估计每秒所需的读写次数,您可以将这些数字插入公式中,看看您的磁盘子系统是否能跟上。也许你无法控制硬件

  • 您是否会将插入内容包装在事务中,这会使它们在插入完成之前对读取不可用

  • 如果您的硬件配置正确,并且您正在关注您的SQL编码,那么应该遵循这一点——看起来您是这样的

  • 查看SQLIO.exe和SQL压力工具:

    SQLIOStress.exe SQLIOStress.exe模拟SQL Server 2000 I/O行为的各种模式,以确保基本的I/O安全

    SQLIOStress实用程序可以从Microsoft网站下载。请参阅下面的文章

    •如何使用SQLIOStress实用程序对磁盘子系统(如SQL Server)施加压力

    重要信息下载包含一份完整的白皮书,详细介绍了该实用程序

    SQLIO.exe SQLIO.exe是用于建立基本基准测试结果的SQL Server 2000 I/O实用程序

    SQLIO实用程序可以从Microsoft网站下载。见下文: •SQLIO性能测试工具(SQL开发)-客户可用

    如果您运行的是SQL 2005及以上版本,请查看实现。您将无法使用nolock获得一致的结果


    在SQL 2000上解决这个问题要困难得多。

    这是SQL Server 2005/2008企业级分区功能的一个很好的方案。您可以为每个StationID创建一个分区,并且每个StationID的数据可以进入其自己的文件组(如果需要,可能不需要,具体取决于您的负载)

    这为并发性带来了一些优势:

    • 如果按stationid进行分区,则用户可以对当前未加载的stationid运行select查询,并且不会遇到任何并发问题
    • 如果按stationid分区,则多个工作站可以同时插入数据,而不会出现并发问题(只要它们位于不同的文件组上)
    • 如果按syncid范围进行分区,则可以将较旧的数据放在较慢的存储上
    • 如果按syncid范围进行分区,并且范围足够小(意味着没有包含数千个syncid的范围),则可以在用户查询的同时进行加载,而不会出现并发问题
    您描述的场景与数据仓库夜间加载有很多共同之处。微软做了一个名为project Real的技术参考项目,你可能会感兴趣。他们将其作为标准发布,您可以通读设计文档和实现代码,以了解他们是如何快速加载的:


    分区在SQLServer2008中甚至更好,尤其是在并发性方面。它仍然不是一颗灵丹妙药——它需要熟练的DBA进行手动设计和维护。它不是一个一成不变的特性,它需要企业版,这比标准版要贵。不过,我很喜欢它——我已经使用过好几次了,它为我解决了一些具体问题。

    将此作为答案,因为“解决方案”的一部分与正确设置特定的磁盘系统有关,这大大提高了按stationid分区的吞吐量。另一个好处是:如果您创建了正确的聚集索引(stationid,syncid)在synctable上,(syncid)在datatable上,并对syncid使用标识。您永远不会从insert活动中获得页拆分,这允许您对select语句使用READPAST,这样就不会干扰insert活动(他们不会等待获得X锁定记录的S锁,并且在没有更新的情况下,不会为任何S锁定行发出X锁)。如果可以进行页面拆分,READPAST有时可能会导致不一致的结果,这是一个危险的选项。
    [SyncTable]
      SyncID
      StationID
      MeasuringTime
    
    
    [DataTypeTable]
      TypeID
      TypeName
    
    
    [DataTable]
      SyncID
      TypeID
      DataColumns...
    
    INSERT INTO SyncTable(StationID, MeasuringTime) VALUES (X,Y); SELECT @@IDENTITY
    
    INSERT INTO DataTable(SyncID, TypeID, DataColumns) VALUES 
      (SyncIDJustInserted, InMemoryCachedTypeID, Data)
      ... lots (500) similar inserts into DataTable ...
    
    SELECT SyncID FROM SyncTable WHERE StationID = @StationID 
                                   AND MeasuringTime = @MeasuringTime 
    SELECT DataColumns FROM DataTable WHERE SyncID = @SyncIDJustSelected
                                      AND DataTypeID = @TypeID