我正在开发一个Web应用程序,目前正在使用sql server 2008。但是,我正在考虑转移到另一个数据库(simpledb)以提高性能。
我有一个后台进程,每小时最多可以将10000行插入到一个特定的表中。该表也被读取以显示Web应用程序中的数据。后台进程运行时,Web应用程序无法使用,因为数据库连接超时。
因此,我正在考虑转向亚马逊的simpledb来提高性能。亚马逊的SimpleDB是否针对此用例进行了优化?如果没有,我可以使用另一种解决方案吗?
答案 0 :(得分:20)
您的问题是您正在使用的隔离级别。除非您更改它,否则SQL Server(以及许多其他数据库)将以选择将阻止未提交读取的模式运行。您希望更改SQL Server,使其改为使用MVCC(Oracle的默认设置; MySQL和SQL Server也都使用它),您的问题就会消失。
来自SET TRANSACTION ISOLATION LEVEL (Transact-SQL):
READ COMMITTED
指定无法读取语句 已修改但未修改的数据 由其他交易承诺。这个 防止脏读。数据可以 由其他交易改变 个人陈述 当前交易,导致 不可重复的读取或幻像数据。 此选项是SQL Server的默认选项。
READ COMMITTED的行为取决于 关于设置 READ_COMMITTED_SNAPSHOT数据库 选项:
- 如果READ_COMMITTED_SNAPSHOT设置为OFF(默认值),则为数据库引擎 使用共享锁来防止其他 来自修改行的事务 当前事务正在运行 读操作。 共享锁也 阻止语句读取行 由其他交易修改,直到 另一笔交易完成。 共享锁定类型确定何时 它将被释放。行锁是 在下一行之前发布了 处理。页锁已发布 当读取下一页时,和表 在声明时释放锁 饰面。
- 如果READ_COMMITTED_SNAPSHOT设置为ON,则数据库引擎使用行 版本化以呈现每个陈述 具有事务一致性 存在的数据快照 声明的开头。锁是 不用于保护数据 其他交易更新。
当READ_COMMITTED_SNAPSHOT时 数据库选项是ON,你可以使用 READCOMMITTEDLOCK表提示 请求共享锁定而不是行 个别陈述的版本控制 在READ中运行的事务中 委托隔离级别。
(强调补充)
更改数据库配置以将READ_COMMITTED_SNAPSHOT变为ON。
此外,尽量保持您的事务尽可能短,并确保您在后台进程中提交事务(每小时执行10,000次插入),因为如果它从未提交,则选择将永久阻止(默认情况下)设置)。
答案 1 :(得分:5)
正如其他人所说,您写入数据库的数据量不是问题。 SQL Server可以轻松处理比这更多的数据。就个人而言,我每小时都有数十万到数百万行没有问题,而且人们整天都在阅读这些行而没有任何减速。
您可能需要通过更改read语句的隔离级别或使用WITH(NOLOCK)提示来查看脏读。
您应该查看使用.NET中的批量上传对象将数据加载到数据库中。根据您在测试期间看到的性能,使用1000-5000的批次。您需要使用该数字才能获得最佳性能。将数据大量插入表中将比逐行插入记录提供更好的性能。确保您不在单个事务中执行整个上载。您应该每批执行一次交易。
写入数据库时,磁盘IO的外观如何。
您为数据库设置了哪种恢复模式?与使用SIMPLE恢复模式相比,数据库上的完全恢复将需要更多的IO。如果您确实需要随时恢复的时间点,请仅使用完全恢复。
答案 2 :(得分:2)
每秒3次插入不会给任何DBMS锻炼,除非每次插入操作中插入的数据量是惊人的。同样,每秒10次读取不太可能过度压力任何有能力的DBMS,除非你没有提到一些复杂的因素(例如'读取是整个DBMS上聚合的聚合,这将在一段时间后累积数十亿条记录......对于前十亿条记录,大约需要10,000小时,大约是4,000天,大约是10年。)
答案 3 :(得分:0)
在Joel的回答的后续内容中,您可能需要查看为索引设置PAD_INDEX和FILLFACTOR的适当值。如果您没有指定这些选项,那么您的插入可能会对索引进行大量重新分页,这会大大减慢您的写入时间。