我们从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;


对于210,000次数据插入,它执行了1,100,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:


  感谢您的信息。我们已重现该问题并正在调查中。如果有任何结果,我们会尽快通知您。

最佳答案

在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/

10-09 13:07