我在Sql Server 2008中有一个名为 PhotoStorages 的表,其中包含以下列。该表包含5000个数据。
PhotoStorageId bigint
Photo image
目前我正在使用C#加载数据,如下所示
string sql = "SELECT * FROM PhotoStorages";
using (SqlCommand sqlCommand = new SqlCommand(sql))
{
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(sqlCommand))
{
using (DataTable dataTable = new DataTable())
{
dataAdapter.Fill(dataTable);
if (dataTable.Rows.Count > 0)
{
for (int i = 0; i < dataTable.Rows.Count; i++)
{
/*Resize the image and again update those resized image to the same database table*/
}
}
}
}
}
现在这个过程的执行非常缓慢。我想知道有没有其他方法来实现这一目标。提前谢谢!
答案 0 :(得分:2)
您可以使用SQL Server中的ROW_NUMBER
函数将查询分解为更小的块,以对结果进行分页。
我在这个问题的答案基础上: Paginate rows from SQL
首先,您必须将查询转换为执行分页的查询:
string sql = @"SELECT
*
FROM
(
SELECT
ROW_NUMBER() OVER(ORDER BY Id DESC) AS RowNumber,
*
FROM
PhotoStorages
) AS T
WHERE
RowNumber BETWEEN @start AND @start + @pageSize";
您应该更改ORDER BY Id
以匹配查询的实际ID列。在您的特定情况下,您可以使用表格中的任何列,因为您使用的是所有数据,您不必担心返回的订单。在宏观方案中5000行并不大,但如果它是一个超过100,000行的大表,你会想要使用一个有索引的列。并且不要使用二进制数据列。
然后你可以在循环中运行你的查询:
var pageSize = 10;
var startAt = 0;
while(true)
{
using (SqlCommand sqlCommand = new SqlCommand(sql))
{
sqlCommand.Parameters.Add("@start", SqlDbType.Int).Value = startAt;
sqlCommand.Parameters.Add("@pageSize", SqlDbType.Int).Value = pageSize;
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(sqlCommand))
{
using (DataTable dataTable = new DataTable())
{
dataAdapter.Fill(dataTable);
var rowCount = dataTable.Rows.Count;
var startAt = startAt + rowCount;
if (dataTable.Rows.Count > 0)
{
for (int i = 0; i < dataTable.Rows.Count; i++)
{
/*Resize the image and again update those resized image to the same database table*/
}
}
else
{
break;
}
}
}
}
}
我们的想法是选择一定数量的行(我们通过pageSize
变量提供这些行。然后我们将这些行调整大小,然后继续循环。循环将继续,直到查询返回no用于pageSize
的值取决于你,但作为一个例子,如果你有2GB的可用内存,并且每张照片是2MB,如果你的pageSize是1000行,你将非常粗略地使用所有内存。您希望使用基本少于所有可用内存,因为这不仅会减慢此过程,还会降低计算机上需要空闲内存的所有其他过程。
我的C#技能非常生疏,但希望这对你有用。