sql-server - SQL Server 2008 R2 上的插入和选择性能

标签 sql-server database sql-server-2008

我们有一个带有相当大表(但不是很大)的 SQL Server - 每个表可能有 30-40 百万条记录。

我们需要

a) 每秒向其中一个表插入大约 1000 条记录(在某些时候 - 但我们不能批量插入),比如 TABLE_A 和 b) 同时从 TABLE_B 中选择 *,其中 id = _SOME_GUID_ID

我注意到 (a) 目前在负载下需要 500-600 毫秒(考虑到我们无法对它们进行批处理,因此每次插入)并且 (b) 需要大约 400 毫秒(有一个索引)

这与我们正在寻找的性能相去甚远。有什么方法可以优化这些表/操作吗?

当前服务器有 16gb 的 ram,数据库总大小约为 40gb。我们预计这些表格在未来几个月内会增加 10 倍。我们可以使用 Sql Server 进行任何类型的分片吗?我们会看到使用 MySQL Percona 构建的任何性能改进吗?

希望这是有道理的。我想补充一点,我们使用的是 NHibernate,但上述性能是插入数据库所花费的毫秒数——不包括应用程序或 nh 开销。

谢谢, 雅尼斯

最佳答案

我想到了几件事。什么是主键,它是一个 GUID 还是整数,如果它是一个 GUID 并且你聚集在它上面,那么 SQL Server 将不得不在许多不同的地方而不是顺序地插入。您的数据库大小,日志大小还是它们一直自动增长,请参阅 Sizing database files

运行探查器并查看 nhibernate 创建的 SQL 类型。 每秒 1000 次插入不再令人印象深刻,瓶颈也可能是硬件,确保它的大小和配置正确。 tempdb、日志和数据文件是否在同一个驱动器上?如果是这样,将它们移动到单独的驱动器

另一种选择是重写执行这些插入的部分并批处理它们而不是单行插入

这是我从 SSMS 运行的示例,它在 166 毫秒内执行 4999 次插入,在 40 毫秒内执行 1000 次

CREATE TABLE Sometest(id INT PRIMARY KEY, 
SomeCol VARCHAR(200), SomeDate DATETIME,SomeCol2 VARCHAR(200), 
SomeDate2 DATETIME,SomeCol3 VARCHAR(200), 
SomeDate3 DATETIME,SomeCol4 VARCHAR(200), SomeDate4 DATETIME)
GO




DECLARE @start DATETIME = GETDATE()
SET NOCOUNT ON
DECLARE @id INT =1
WHILE @id < 1000
BEGIN
    INSERT Sometest
    SELECT @id ,'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla111111',GETDATE(),
    'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla2222',GETDATE(),
    'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla3333',GETDATE(),
    'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla4444',GETDATE()
SET @id+=1
END




SELECT DATEDIFF(ms,@start,GETDATE())
SELECT COUNT(*) FROM Sometest

如果将整个事情包装在一个事务中,它会快得多,50000 次插入需要 800 毫秒,5000 次插入需要 103 毫秒,1000 次插入需要 23 毫秒

TRUNCATE TABLE Sometest
DECLARE @start DATETIME = GETDATE()
SET NOCOUNT ON
BEGIN tran
DECLARE @id INT =1
WHILE @id < 50000
BEGIN
    INSERT Sometest
    SELECT @id ,'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla111111',GETDATE(),
    'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla2222',GETDATE(),
    'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla3333',GETDATE(),
    'BlaBlaBlaBlaBlaBlaBlaBlaBlaBla4444',GETDATE()
SET @id+=1
END
commit
SELECT DATEDIFF(ms,@start,GETDATE())
SELECT COUNT(*) FROM Sometest

在你的系统上用一个看起来像你的表的表运行类似的东西并调查问题是什么,也许你需要调整文件大小、分离文件、对表进行碎片整理等等等等

关于sql-server - SQL Server 2008 R2 上的插入和选择性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15389318/

相关文章:

java - 如何最好地将我的应用程序与不可靠的数据库隔离开来?

database - 单元测试数据库转换有什么好的策略或工具? (不是单元测试数据库,而是转换)

mysql - 如何在 MySQL 中添加注释?

sql-server - 在 SQL Server Business Intelligence Development Studio 中将多值参数转换为临时表

sql-server - Unix ODBC Connect 2016 MS SQL Server sql 状态 28000 native 错误 18456

mysql - 如何更新mysql中新添加的列

使用 group by 进行 SQL Server 更新

在 SQL Server 2008 上创建表的 SQL 注释

python - 将 None 作为参数值传递给 SQL Server 时出现意外行为

c# - 使用 Linq 将 SQL Server 数据库表导出到 XML