delphi - Unidac 5.0 性能下降

标签 delphi postgresql-9.1 unidac

我们从 UniDAC 4.1 迁移到 5.0(只需重建或使用新版本的应用程序),并在我们的数据泵例程中发现巨大的性能下降。

运行 pgfouine 捕获许多查询,例如:

SELECT current_database() AS DATATYPE_CATALOG, 
n.nspname AS DATATYPE_SCHEMA,
t.typname AS DATATYPE_NAME,
t.oid AS DATATYPE_OID,
t.typlen AS DATATYPE_LENGTH,
CASE WHEN t.typtype = 'b' THEN 'base' 
    WHEN t.typtype = 'c' THEN 'composite' 
    WHEN t.typtype = 'd' THEN 'domain' 
    WHEN t.typtype = 'e' THEN 'enum' 
    WHEN t.typtype = 'p' THEN 'pseudo' 
END::varchar(9) AS DATATYPE_TYPE,
t.typrelid AS TABLE_OID, 
t.typbasetype AS DATATYPE_BASETYPE 
FROM pg_type t 
INNER JOIN pg_namespace n ON n.oid = t.typnamespace 
WHERE t.oid = '' AND t.typtype = '' 
ORDER BY n.nspname, t.typname;

它执行了超过 1,100,000 次,插入了 210,000 条数据。 为什么会发生这种情况以及如何在当前版本上避免这种情况?

我们在插入循环之前执行 TUniQuery.Prepare 一次,并在内部重新分配查询参数。 在 UniDAC 4.1 上它运行良好。

UPD。 搜索最小的可复制应用程序/数据库我发现,如果 我们在表中使用域数据类型。

    CREATE DOMAIN id_dom AS integer NOT NULL;
    CREATE TABLE test_table (id id_dom);

最小应用:

    program minProject;

    {$APPTYPE CONSOLE}
    uses
    Messages, SysUtils, Variants,
    DB, DBAccess, Uni, UniProvider, PostgreSQLUniProvider;

    const text = 'insert into test_table (id) values (:id)';

    var
    qu:TUniQuery;
    PostgreSQL: TPostgreSQLUniProvider;
    UniConnection1: TUniConnection;
    i: Integer;
    ids: Variant;

    begin
    { TODO -oUser -cConsole Main : Insert code here }
    UniConnection1 := TUniConnection.Create(nil);
    PostgreSQL := TPostgreSQLUniProvider.Create(UniConnection1);
    UniConnection1.ProviderName := 'PostgreSQL';
    UniConnection1.Username := '';
    UniConnection1.Password := '';
    UniConnection1.Server := '';
    UniConnection1.Database := 'test';
    UniConnection1.SpecificOptions.Values['ProtocolVersion'] := 'pv30';
    ids := VarArrayOf([41750, 41751, 41752]);
    qu := TUniQuery.Create(UniConnection1);
    qu.Connection := UniConnection1;
    qu.SQL.Text := text;
    qu.Prepare;
    for I := 0 to 2 do
    begin
        qu.ParamByName('id').AsInteger := ids[i];
        qu.Execute;
    end;
    qu.Close();
    end.

如果使用常用的数据类型,一切都可以。

UPD2:

Answer from DevArt:

Thank you for the information. We have reproduced the problem and are investigating it. We will inform you as soon as we have any results.

最佳答案

在 5.0.1 版本中添加了对域类型的完全支持(4.1 版本中没有),因此我们必须从数据库请求额外的元数据。 我们发布了 UniDAC 的新版本 - 5.0.2 - 它包含一个修复程序,可提高处理域类型时的性能。现在,即使查询包含具有域数据类型的字段,UniDAC 的运行速度也与 UniDAC 4.6.12 一样快。

关于delphi - Unidac 5.0 性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16610947/

相关文章:

delphi - 设置 Delphi XE 使用 Vim 作为默认合并查看器

delphi - 如何调整GLCamera显示整个GLScene

sql - PostgreSQL 中的 WHERE NOT EXISTS 给出语法错误

mysql - 如何通过 dbgrid 更改 mysql 数据库的值?

MySQL : start Transaction if a condition was true

delphi - 当拥有框架的表单被激活/停用时,是否有一种简单的方法来调用框架中的方法?

delphi - Delphi XE 中有带标题的虚拟列表框吗?

postgresql - 如何从另一个 php 文件使用 PostgreSql 的 CURRVAL/RETURNING?

postgresql - 减去 2 hstore,您可能需要添加显式类型转换