c#数据集。用Firebird 2.5解决可怕的性能问题
备注我完全重写了这个问题,因为在探索选项和获得见解的同时,我意识到问题的根源根本不是我所想的 我使用Firebird作为数据库引擎,并使用标准.Net提供程序(v.5.11.0)使用以下代码获取数据:c#数据集。用Firebird 2.5解决可怕的性能问题,c#,performance,firebird,firebird2.5,dataadapter,C#,Performance,Firebird,Firebird2.5,Dataadapter,备注我完全重写了这个问题,因为在探索选项和获得见解的同时,我意识到问题的根源根本不是我所想的 我使用Firebird作为数据库引擎,并使用标准.Net提供程序(v.5.11.0)使用以下代码获取数据: // myBlob1 is BLOB SUB_TYPE 1 (text field) with some empty, but some // VERY long stuff (xml-content) which exceeds VARCHAR(32765), but I removed //
// myBlob1 is BLOB SUB_TYPE 1 (text field) with some empty, but some
// VERY long stuff (xml-content) which exceeds VARCHAR(32765), but I removed
// those before performing my tests!!!
var tick = Stopwatch.StartNew();
DataTable dataTable = new DataTable();
DbLive.Open();
FbCommand command = new FbCommand("SELECT myBlob FROM MY_TABLE", DbLive);
try {
dataTable.BeginLoadData();
FbDataAdapter fda = new FbDataAdapter(command);
fda.Fill(dataTable);
dataTable.EndLoadData();
}
command.Dispose();
DbLive.Close();
tick.Stop();
Console.WriteLine("Execution time: " + tick.ElapsedMilliseconds + " [ms]");
根据database workbench的统计数据,我总共获取了大约30k行,其中包含大约16Mb的数据,但只有20k行包含非空数据
因此,我使用naive方法获取整个内容,然后使用cast(VARCHAR(8192))
方法(注意,在进行测试之前,我删除了所有带有>8192个字符的行)。现在,以下是结果:
// Obtained when loading data over wifi, with a bandwidth of about 100Mbps)
// the performance on local machine did not make a big difference!)
No casting: 73287.0788 ms
With casting: 2360.2244 ms
这里的Blobs
确实有些不好的地方。我使用Firebird 3和compression测试了性能,但结果并没有太好(改进很小,但差异仍然是相同数量级)
切中要害:
1.如果我使用另一个提供商(如建议的www.ibprovider.com
,但我无法对其进行测试),我是否可以期待改进
2.这是其他数据库引擎上的一个已知问题,还是有希望通过更改到另一个引擎来获得改进?我对上面提到的许多事情感到有点困惑,所以让我澄清一些见解:
FbDataReader
和Dapper
方法实际上没有加载blob字段,因此性能确实是无关紧要的CAST
到VARCHAR(4096)
确实显示了显著的性能改进(注意,在这里,我测试了文本blob的内容以完全匹配,这确实有效):
数据表编号:73287.0788毫秒
FbDataReader广播:2224.1387毫秒
数据表广播:2360.2244毫秒BLOB
而不是largeVARCHAR
导致了这个问题
请注意,我没有成功地与其他提供商进行测试
一句话:在这里使用
BLOB子类型1
会降低我的性能,我应该改用VARCHAR
。在使用Firebird 3 embedded和FBDataAdapter读取BLOB文本字段时,我遇到了类似的性能问题。查询本身似乎不是问题所在——它在Flamerobin中执行得相当快。然后我注意到Visual Studio报告了一系列的:
微软C++异常:FielBoo::内存位置的StasuSub异常 0x0000007DD010B920
尽管调用.Net应用程序看不到这些异常 事实证明,大部分的放缓显然是由于VisualStudioIDE试图处理引发的许多异常。对于读取的每个BLOB字段,都会引发一个“安静”异常。当通过isc\u get\u segment
读取BLOB的“segments”时,会发生这种情况,该过程会重复调用,直到所有segments都已读取isc_get_segment
显然在遇到数据结尾时会在后台抛出异常
当我在Visual Studio IDE和调试器下运行时,这会减慢速度,但如果我自己运行应用程序,性能是合理的。好吧,我们知道我们不是在看真正的代码,因为代码段总是会引发异常。那我们还不知道什么是你应该告诉我们的?我的坏习惯和格式有关。。。抛出当然应该放在括号中……默认情况下,Flamerobin不会获取所有行,它只获取几页,默认情况下,Flamerobin不会获取blob(仅按需)。这可能也适用于Database Workbench.blob存储在表外,需要额外的网络往返。因此,在网络速度瓶颈的情况下,吞吐量可能会降低2-3倍。你们真的是大块头吗?您可以尝试取消blob它们
选择。。。强制转换(BlobField为VarChar(1024))。。。但是,请注意,Firebird上的总行大小限制为32 KB,UTF-8编码的字符串/BLOB每个字母占用4字节。U仍然没有显示表的SQL模式,也没有对无BLOB查询方法进行注释。我只能说,//iterate-throw-each不做任何事情
B方法不获取blob,因此竞争是不正确的。你真的应该设置所有的数据。所以是整洁是T记录不包括一些斑点文件澄清的事情是好的。在错误的地方澄清事情是不好的,也是令人困惑的。请,1)编辑您的问题并在此处添加新的详细信息,2)在Q下添加评论,通知您更新了Q并提供了更多详细信息,3)删除此“答案”,因为它不是allI的答案,我编辑了您的答案并删除了应视为后续问题的部分。请注意,这些后续问题可能比堆栈溢出更适合firebird-devel或firebird-net提供程序邮件列表。