2

我有一个 VB Web 应用程序,它从包含大约 300,000++ 行的 CSV 文件中读取。应用程序将逐行读取,并且对于每一行,它将查询包含大约 100,000++ 条记录的 sql server 数据库中的表,并根据查询结果,应用程序将执行其他操作。sqlservr.exe 在我的 4GB 开发机器中最大限度地消耗内存。

所以我创建了一个简单的应用程序来测试 sql server 在循环查询方面的性能。

Dim Connection As New SqlConnection(ConfigurationManager.ConnectionStrings("SiteSqlServer").ConnectionString)
Dim Command As New SqlCommand("", Connection)
Connection.Open()
For i As Integer = 0 To 20000
    Command.CommandText = "SELECT CustomerID FROM Customer WHERE CustomerID = " & i
    Command.ExecuteScalar()
Next
Connection.Close()

每次执行此代码时,sqlservr.exe 将占用额外的 100MB++ 内存,即使在代码执行完成后它也不会释放它。

这是正常的吗?有什么办法可以减轻这种影响吗?

4

3 回答 3

2

试试这个:

For i As Integer = 0 To 20000
    Command.CommandText = "SELECT CustomerID FROM Customer WHERE CustomerID = " & i
    Command.ExecuteScalar()
    Command.Dispose()
Next

呼叫应该在Dispose()您身后清理并可能减轻影响。

于 2011-06-13T13:54:29.360 回答
2

Sql Server 不会立即将内存释放回系统,原因有几个(参见:http ://sqlnerd.blogspot.com/2006/07/memory-use-in-sql-server.html )。

无论如何,您应该使用存储过程而不是动态 sql 查询:Sql Server 可以更有效地工作,因为您的 sql 字符串不必每次都被解析。

确实如此,但请仔细检查 - 确保您正在查询的表已正确编入索引。

您也可以考虑预先将您的 .csv 文件加载到 sql server - 如果可行的话。将 .csv 数据放在 sql server 索引表中将使一切变得更容易:无论您如何优化它们,到 Sql Server 的 100k 次往返都将消耗您可以通过利用连接和服务器轻松节省的资源-副业。

于 2011-06-13T13:59:04.757 回答
0

是的,这很正常。SQL Server 通常不会在获得内存后释放它。它的目的是尽快将结果提供给您,如果它有数据缓存在 RAM 中,则可以更快地查询。SQL Server 可能会重新利用它在内部获取的内存块,但它不会在运行时释放它们。这是设计使然。试试看这个

This is also why, in general, you should run SQL Server on a separate box in production, so it doesn't contend with other applications for memory (such as IIS).

于 2011-06-13T13:59:37.720 回答