实现具有许多插入,删除和读取的数据表的最佳实践是什么?

时间:2009-05-13 07:38:58

标签: c# sql-server-2005 ado.net

我正在创建一个功能,我们的wcf服务会记录通过它们存储的所有更改,并且需要将更改发送到其他系统。

每次更改服务后,我们都会将更改存储在表中(更改已序列化)。我们有规律地从表中提取更改并删除拉出的更改。

这意味着在高负载期间插入和删除的数量很高,我们很难选择超时,因为插入会阻止它。

我尝试使用不同的隔离级别,但还没有找到任何可行的功能。

我们使用ado.net和sql server 2005。

使用sql server 2005和ado.net时,实现包含许多插入,删除和读取的数据表的最佳做法是什么。

编辑: 我们今天解决方案中的问题是所有继续插入都会停止从表中读取所有内容。可能是因为如果一个clustred索引扫描我认为暂时没有好的方法可以删除。

4 个答案:

答案 0 :(得分:1)

在数据库方面:

  • 尝试使用名为READPAST的锁定提示,该提示会跳过由其他事务锁定的行。有关详细信息,请参阅MSDN
  • 如果Sql Server认为它更经济,有时会将锁从行级升级到页级或表级。您可以使用提示ROWLOCK强制将锁保持在行级别。
  • 删除所有不必要的索引,因为它们会降低插入,更新和删除速度,还会导致索引数据出现锁定问题。

在C#代码方面:

  • 使用“尽可能晚地获取资源并尽早发布”的最佳做法。打开ADO.NET连接,运行sql命令并关闭连接,然后对结果执行任何耗时的操作。您不必担心连接池,只要您始终使用相同的连接字符串,它就会自动完成。

答案 1 :(得分:0)

这是您的DBA应该做的事情。你是DBA吗?如果是这样,那么你需要看看运行一些性能测试,看看瓶颈是什么。本文应该作为性能调优的介绍帮助:http://www.devx.com/getHelpOn/Article/8202/

答案 2 :(得分:0)

如果您的应用程序的语义允许,请考虑插入单独的“辅助表”并定期将它们应用于单个大型事务中的“主表”;删除可以类似地处理(现在你要删除,而是插入到一个记录的单独辅助表中,用于标识要删除的主表记录),并定期从一个大表中执行一堆删除操作交易)。

当然,如果你这样做,主表不会反映“最新状态”,而是“几分钟[或任何时间单位]之前的状态”,这就是为什么我说“如果语义允许”。有时可以让许多SELECT依赖于“上次更新时的状态”(即主表中的内容)和一些真正需要立即反映最新更新的SELECT可以满足(可能有点慢)更复杂查询使用主表和辅助表(通过UNION,连接或其他任何方式,具体取决于您需要实现的语义的细节)。

答案 3 :(得分:0)

您提到您尝试过不同的隔离级别,但是您尝试过快照隔离吗?

快照隔离基本上是在插入/更新之前创建行的副本,并且尝试选择该行的任何查询都会获得旧副本,直到插入完成为止。这意味着您偶尔会收到稍微较旧的数据,但在插入时不会阻止选择。

这样做的缺点是,由于需要复制,您的插入/更新将需要更长时间。我不确定它会产生多大的惩罚。