SQL: Fazendo atualização sequencialmente .Write na coluna varbinária
-
20-09-2019 - |
Pergunta
Estou tentando criar um pequeno aplicativo de teste que lê pedaços de um FileStream e o anexa a uma coluna Varbinária (MAX) em um SQL Server 2005 Express.
Tudo funciona - a coluna é preenchida como deveria, mas minha máquina ainda parece amortecer tudo na memória e eu simplesmente não consigo ver o porquê.
Estou usando o seguinte código (c#):
using (IDbConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings[1].ConnectionString))
{
connection.Open();
string id = Guid.NewGuid().ToString();
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = "INSERT INTO [BLOB] ([Id],[Data]) VALUES (@p1,0x0)";
SqlParameter param = new SqlParameter("@p1", SqlDbType.VarChar);
param.Value = id;
command.Parameters.Add(param);
command.ExecuteNonQuery();
}
if (File.Exists(textBox1.Text))
{
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = "UPDATE [BLOB] SET [Data].WRITE(@data, @offset, @len) WHERE [Id]=@id";
SqlParameter dataParam = new SqlParameter("@data", SqlDbType.VarBinary);
command.Parameters.Add(dataParam);
SqlParameter offsetParam = new SqlParameter("@offset", SqlDbType.BigInt);
command.Parameters.Add(offsetParam);
SqlParameter lengthParam = new SqlParameter("@len", SqlDbType.BigInt);
command.Parameters.Add(lengthParam);
SqlParameter idParam = new SqlParameter("@id", SqlDbType.VarChar);
command.Parameters.Add(idParam);
idParam.Value = id;
using (FileStream fs = new FileStream(textBox1.Text, FileMode.Open, FileAccess.Read, FileShare.Read))
{
byte[] buffer = new byte[2090400]; //chunk sizes that are multiples of 8040 bytes.
int read = 0;
int offset = 0;
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
{
dataParam.Value = buffer;
offsetParam.Value = offset;
lengthParam.Value = read;
command.ExecuteNonQuery();
offset += read;
}
}
}
}
}
Alguém pode me dizer por que isso buffer o arquivo na memória? o byte[]
O buffer que estou usando tem apenas quase 2 MB de tamanho.
Eu poderia criar um novo buffer para cada pedaço, mas isso parece um desperdício de CPU/memória também ...
Solução
Ele o buffer porque, quando você o salva na coluna varbinária, ele se torna parte do cache de dados do LOB no SQL Server. é assim que funciona.
Ou você quer dizer que é buffer em outro lugar?
Outras dicas
A entrada de buffers de classe filestream entrada e saída. Você pode chamar o método Flush () após cada atualização para limpar os buffers internos.
Para ficar claro, ele apenas buffer no tamanho do buffer (4 kb).
Nesse caso, acho que seu culpado é o SQLEXPRESS. Quando executei seu código e escrevi na minha cópia local do SQLEXPress, o uso da memória pelo processo SQLSRVR saltou em torno de 1 GB. Quando escrevi para um banco de dados não local, meu uso de memória permaneceu plano.