Firebird 插入速度很慢

标签 firebird dbexpress c++builder-xe2

我在 Firebird 数据库上执行 INSERT 语句缓慢时遇到问题。性能值如下:

在装有 Windows XP 的笔记本上插入 3800 条记录大约需要 31 秒(每秒大约 120 条插入)。在另一台装有 Windows 7 32 位的 PC 上,执行相同的任务需要 80 秒(约每秒 50 次插入)!使用的Firebird版本是2011年10月的2.5.1 SuperServer。使用的连接技术是DBExpress。

这就是我的数据库表的创建方式:

CREATE TABLE RESULTS
(
    POS         INTEGER,
    FIELD_CODE  VARCHAR(255),
    FIELD_DESC  VARCHAR(255),
    ORD         INTEGER,
    RVALUE      VARCHAR(2048),
    DETAIL      VARCHAR(2048)
);

这是访问它的源代码。与现实相比,它有些简化(不包括调用者方法),但确实包括所有基本内容。 Profiler 显示该特定方法是瓶颈。一次调用大约需要 10 毫秒。因此 3800 个调用大约需要 38 秒。

Field *field = NULL;
int ord = GetFieldOrder(field_code, &field);
if (field == NULL)
{
   return -1;
}

AnsiString sql;
sql.printf("delete from RESULTS where POS = %d and ord = %d", position, ord);
try
{
   Query_SQL->CommandText = sql;
   Query_SQL->ExecSQL();
}
catch (Exception &e)
{
}

if (field->write_field_code)
{
   field_code.printf("'%s'", field->field_code);
}
else
{
   field_code = "NULL";
}
AnsiString field_description;
if (field->write_field_description)
{
   field_description.printf("'%s'", field->field_description);
}
else
{
   field_description = "NULL";
}
sql.printf("insert into RESULTS (POS, FIELD_CODE, FIELD_DESC, ORD, RVALUE) VALUES (%d, %s, %s, %d, '%08X')", position, field_code, field_description, ord, value);

try
{
   Query_Insert->Params->Items[0]->AsInteger = position;
   Query_Insert->Params->Items[1]->AsString = field_code;
   Query_Insert->Params->Items[2]->AsString = field_description;
   Query_Insert->Params->Items[3]->AsInteger = ord;
   Query_Insert->Params->Items[4]->AsString = value;
   Query_Insert->Params->Items[5]->Clear();
   Query_Insert->ExecSQL();
   // Query_SQL->CommandText = sql;
   // Query_SQL->ExecSQL();
}
catch (Exception &e)
{
   return -1;
}
return 0;

正如您从代码的注释部分看到的,我尝试参数化 SQL 查询以加快其重复执行速度,但没有进行重大更改。所有调用都在事务内部:

TDBXTransaction *transaction = DataModule->Database->BeginTransaction();

unsigned int i;
unsigned int c = meters.size();
for (i = 0; i < c; i++)
{
            ...
    DataModule->InsertDefaultValues(meters[i]); // <---- here are our INSERTs
            ...
}

DataModule->Database->CommitFreeAndNil(transaction);
transaction = NULL;

gstat -h 命令对数据库文件的输出如下:

Database "C:\ELMA\EDEX\CAL_RESULTS.FDB"

Database header page information:

Flags           0
Checksum        12345
Generation      33255
Page size       4096
ODS version     11.2
Oldest transaction  33246
Oldest active       33247
Oldest snapshot     33247
Next transaction    33248
Bumped transaction  1
Sequence number     0
Next attachment ID  60
Implementation ID   16
Shadow count        0
Page buffers        0
Next header page    0
Database dialect    1
Creation date       Jul 6, 2013 12:58:03
Attributes      force write

Variable header data:
*END*

firebird.conf 中的默认DbCachePages 为 2048。

删除和插入记录时,fbserver.exe进程充分利用一个CPU核心。

最佳答案

您在 Windows 中启用了“系统还原”吗?如果是这样,请尝试禁用它,看看性能是否会更好。扩展名为 .GDB 的数据库文件也存在问题。如果是这种情况,请尝试将数据库文件重命名为 .FDB。

关于 Firebird 插入速度很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17504543/

相关文章:

c# - Entity Framework 代码优先 - 将 smallint 和整数转换为 int32

delphi - 带有 Delphi 和 dbExpress 的 ASE Syabse 服务器版本

delphi - 如何将所有 TClientDataSet 记录标记为已插入?

C++ 方法指针调用产生 undefined symbol 错误?

c++ - 在 C++ 构建器 XE2 中使用 Windows.Management 命名空间

sql - 是否可以在不安装数据库服务器的情况下打开 Firebird 数据库文件?

sql - 如何确定作为邻接列表模型构建的表中的 'nesting level'

sql - Firebird 无法识别 group by 子句中的计算列

mysql - Delphi 2010和Dbexpress部署

c++ - 直接调用类操作符