INSERT 命令中的多条插入语句

问题描述 投票:0回答:1

我必须将 Xamarin 应用程序中 SQLite 数据库中的数据下载到 Firebird 数据库中,该数据库位于我的 PC 上的同一 WiFi 网络上,并且我可以通过 IP 地址访问。一切正常,但卸载时间很长。

这是连接字符串:

connessione = @"Server=" + ip_server + @";User=sysdba;Password=XXXXXXXX;Pooling=true;Database=" + ip_server + @":C:\\FirebirdSQL\\Photo.FDB";

这是SQL语句:

string _dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), VarGlobal.dbSQLITE);
var db = new SQLiteConnection(_dbPath);
FbCommand cmdfb = new FbCommand("INSERT INTO photo (id,rifiddir,immaginebit) VALUES (@id,@rifiddir,@immaginebit)", conn);      
cmdfb.Parameters.Add("@id", FbDbType.VarChar);
cmdfb.Parameters.Add("@rifiddir", FbDbType.VarChar);
cmdfb.Parameters.Add("@immaginebit", FbDbType.Binary);
conn.Open();
var tuttelefoto = db.Query<Photo>("SELECT id,rifiddir,immaginebit FROM Photo");
foreach (var singolafoto in tuttelefoto)
{
    cmdfb.Parameters["@id"].Value = singolafoto.Id;
    cmdfb.Parameters["@rifiddir"].Value = singolafoto.rifiddir;
    cmdfb.Parameters["@immaginebit"].Value = singolafoto.immaginebit;
    await cmdfb.ExecuteNonQueryAsync(); 
}

conn.Close();

一切正常,但每次插入需要 10 秒。我想用一行重写代码:

FbCommand cmdfb = new FbCommand(" INSERT INTO PHOTO " +
" SELECT '1', 'one' FROM RDB$DATABASE " +    " UNION ALL SELECT '2', 'two ' FROM RDB$DATABASE " +    " UNION ALL SELECT '3', 'three' FROM RDB$DATABASE " +    " UNION ALL SELECT '4', 'four' FROM RDB$DATABASE ", conn);

照片大小最大为 1.5 Mb。 WiFi 为 166 Mbps。

如何插入文本格式的

byte[]
字段?这能解决我的问题吗?你们中的许多人会告诉我不要直接连接到数据库,而是使用 Web 服务。我知道。但该应用程序仅当手机和电脑处于同一网络时才能工作。

c# firebird firebird-.net-provider
1个回答
0
投票

部分问题在于 Firebird 中 Blob 的上传方式,以及 Firebird ADO.net 提供程序 (FirebirdSql.Data.FirebirdClient) 使用的默认传输大小。

在 Firebird 中,blob 被发送到带外。也就是说,它们的数据不是在执行中内联传输的,而是需要由驱动程序1单独发送。首先,驱动程序需要创建一个 blob,然后以请求/响应方式按块(也称为段)发送数据。这种请求/响应风格引入了额外的延迟。

对于 Firebird ADO.net 提供程序,用于传输 blob 的段大小默认为 8192 字节 (8 KiB),并且可以通过

PacketSize
连接属性进行控制(最大为 32767 字节或 32 KiB) - 1).

例如,对于 1.5 MiB 的照片,默认值

PacketSize
(8192) 表示照片以 192 个数据包传输。如果使用最大值 32767,则以 49 个数据包传输。假设客户端和服务器之间的往返延迟为 10 毫秒,那么这就是 1.9 秒和 0.5 秒之间的差异(这忽略了数据本身读取和传输所需的时间,以及 Firebird 数据库可能需要的时间)花费在存储数据上)。

TL;DR:将

PacketSize
连接属性设置为 32767。


1:从 Firebird 4.0 开始,这个问题可以通过批量执行来部分解决,但是很多驱动程序还不(完全)支持这一点,因为它使执行变得更加复杂

© www.soinside.com 2019 - 2024. All rights reserved.