5

我们有一个系统,从多个站点同时插入大量数据,同时还暴露了一个数据查询接口。架构看起来像这样(抱歉格式不好):

[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

我的问题是我们如何结合插入的事务级别和查询的 NOLOCK/READPAST 提示,以便:

  1. 我们在支持插入的同时最大化系统中的并发性(我们需要存储大量数据,每秒高达 2000 多条记录)
  2. 查询仅从“已提交”同步返回数据(我们不希望结果集包含半插入同步或由于锁跳过而包含一些跳过条目的同步)
  3. 我们不关心查询中是否包含“最新”数据,我们更关心一致性和响应能力,而不是“实时”和最新数据

这可能是非常矛盾的目标,并且可能需要高事务隔离级别,但我对所有技巧和优化感兴趣,以实现对插入和选择的高响应性。如果需要更多细节来消除更多调整和技巧,我将很乐意详细说明。

更新:只需为将来的回复添加更多信息。我们在最初具有 5+ TB 存储的 SAN 网络上运行 SQL Server 2005(可能在 6 个月内 2008)。我不确定 SAn 设置了哪种 RAID,以及我们有多少磁盘可用。

4

3 回答 3

1

如果您正在运行 SQL 2005 及更高版本,请考虑实施快照隔离。使用 nolock 将无法获得一致的结果。

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

于 2008-11-14T00:12:36.553 回答
1

这是 SQL Server 2005/2008 Enterprise 的分区功能的绝佳方案。您可以为每个 StationID 创建一个分区,并且每个 StationID 的数据可以进入其自己的文件组(如果需要,根据您的负载可能不需要。)

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

  • 如果您按 stationid 分区,则用户可以对当前未加载的 stationid 运行选择查询,并且他们根本不会遇到任何并发问题
  • 如果您按 stationid 分区,则多个站可以同时插入数据而不会出现并发问题(只要它们位于不同的文件组上)
  • 如果您按同步 ID 范围进行分区,那么您可以将较旧的数据放在较慢的存储上。
  • 如果您按同步 ID 范围进行分区,并且如果您的范围足够小(意味着不是具有数千个同步 ID 的范围),那么您可以在用户查询的同时进行加载,而不会遇到并发问题

您所描述的场景与数据仓库夜间加载有很多共同点。Microsoft 做了一个名为 Project Real 的技术参考项目,您可能会觉得它很有趣。他们将其作为标准发布,您可以通读设计文档和实现代码,以了解它们如何实现快速加载:

http://www.microsoft.com/technet/prodtechnol/sql/2005/projreal.mspx

分区在 SQL Server 2008 中甚至更好,尤其是在并发方面。它仍然不是灵丹妙药——它需要由熟练的 DBA 进行手动设计和维护。它不是一劳永逸的功能,它确实需要企业版,它的成本高于标准版。不过,我喜欢它——我已经使用了好几次,它为我解决了特定的问题。

于 2008-11-15T12:32:11.147 回答
0
  1. 您将使用什么类型的磁盘系统?如果您有一个大型条带化 RAID 阵列,则写入性能应该很好。如果您可以估计每秒所需的读取和写入,您可以将这些数字代入公式,看看您的磁盘子系统是否能跟上。也许您无法控制硬件...

  2. 您不会将插入包装在事务中,这会使它们在插入完成之前对读取不可用?

  3. 如果您的硬件配置正确并且您正在关注您的 SQL 编码,那么这应该遵循 - 看起来您就是这样。

查看 SQLIO.exe 和 SQL Stress 工具:

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

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

• 如何使用 SQLIOStress 实用程序对磁盘子系统(例如 SQL Server)施加压力 http://support.microsoft.com/default.aspx?scid=kb;en-us;231619

重要 下载包含一份完整的白皮书,其中包含有关该实用程序的详细信息。

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

SQLIO 实用程序可以从 Microsoft 网站下载。请参阅以下内容: • SQLIO 性能测试工具(SQL 开发)- 客户可用 http://download.microsoft.com/download/f/3/f/f3f92f8b-b24e-4c2e-9e86-d66df1f6f83b/SQLIO.msi

于 2008-11-13T19:04:41.557 回答