Advantage Database Server INSERT/UPDATE 查询性能问题

Posted

技术标签:

【中文标题】Advantage Database Server INSERT/UPDATE 查询性能问题【英文标题】:Advantage Database Server INSERT/UPDATE queries performance issues 【发布时间】:2013-06-05 16:50:24 【问题描述】:

我正在使用Advantage Database Server v10 和相应的ADO.NET 提供程序。我发现AdsConnection.Close 在执行INSERT/UPDATE 查询后会花费大量时间。

例如这个示例

class Program

    static void Main(string[] args)
    
        var openTimer = new Stopwatch();
        var closeTimer = new Stopwatch();
        var executeTimer = new Stopwatch();

        for (int ix = 0; ix < 100; ix++)
        
            openTimer.Start();
            using (var cnn = new AdsConnection(
                @"data source=...; ServerType=remote; user id=admin; password=..."))
            
                cnn.Open();
                openTimer.Stop();


                executeTimer.Start();
                using (var cmd = cnn.CreateCommand())
                
                    cmd.CommandText = "SELECT MAX(colUGId) FROM tblUserGroup";

                    var id = (int)cmd.ExecuteScalar() + 1;

                    cmd.CommandText = "INSERT INTO tblUserGroup (colUGId, colName, colDesc) VALUES (:id, :name, :desc)";
                    cmd.Parameters.Add("id", id);
                    cmd.Parameters.Add("name", "Name " + id);
                    cmd.Parameters.Add("desc", "Description " + id);
                    cmd.ExecuteNonQuery();
                
                executeTimer.Stop();


                closeTimer.Start();
            
            closeTimer.Stop();
        

        Console.WriteLine("Open: 0; Execute: 1; Close: 2", openTimer.Elapsed, executeTimer.Elapsed, closeTimer.Elapsed);
    

输出:

Open: 00:00:00.2361612; Execute: 00:00:15.3849932; Close: 00:00:05.4333431

非常有趣的是,为什么在简单的索引和没有任何触发器的简单表中执行 100 次 INSERT 操作需要 15 秒。但最重要的问题是:为什么Close 需要这么长时间?

有什么想法吗?

更新

刚刚对 SQL Server 进行了同样的尝试。它在不同的工作站上运行,这比使用 Advantage 的工作站要快一些。无论如何,我可以看到连接池运行良好(在 SQL Server 的情况下):

Open: 00:00:00.2279668; Execute: 00:00:00.0189551; Close: 00:00:00.0003487

【问题讨论】:

您正在创建和处理 AdsConnection 类 100 次。为什么不只打开一次,执行所有插入,然后关闭? @BradM 我想,连接池的发明是为了让我免于这样做 即。是的,连接池应该可以解决这个问题,另请参阅:devzone.advantagedatabase.com/dz/webhelp/Advantage11.1/… 【参考方案1】:

15 秒肯定很长。既然你提到了索引,我确定你有必要的索引,但要确保colUGId 上有一个索引。如果该索引不存在,select max 查询每次运行时都需要进行全表扫描。如果表比较大,成本可能会很高。

虽然连接池确实消除了每次通过循环获取新连接的成本,但所示代码导致所涉及的表在每次迭代时都完全关闭。所以服务器最终通过循环每次打开和关闭表(假设在执行此测试时没有其他用户打开它)。这肯定会增加成本,尽管我不知道为什么会导致报告的时间。

虽然它没有回答问题,但我运行了上面的确切代码(当然修改了连接字符串)并生成了这些数字:

Open: 00:00:00.8909295; Execute: 00:00:01.4729069; Close: 00:00:01.4211188

出于好奇,我将连接的获取移到循环之外并再次运行它。这允许表在执行之间保持打开状态。结果是这些数字:

Open: 00:00:00.1073400; Execute: 00:00:00.0802774; Close: 00:00:00.0270569

编写代码时要注意的另一件事是它不能重用任何准备好的语句。特别是,同一命令对象用于 SELECT 和 INSERT。这导致每次迭代都会解析语句并检查语义。这当然不是一件大事,但它可以加起来。我使用两个命令对象再次运行测试并得到这些数字:

Open: 00:00:00.0835544; Execute: 00:00:00.0567687; Close: 00:00:00.0267799

【讨论】:

以上是关于Advantage Database Server INSERT/UPDATE 查询性能问题的主要内容,如果未能解决你的问题,请参考以下文章

从 Advantage Database Server 10.1 表中删除重复行

Code First 的 Advantage Database Server 11 连接字符串

如何生成与 Advantage Database Server 格式相同的 GUID 字符串?

如何在 Delphi Code 中获取 Advantage Database Server 安装的许可证计数

Advantage Database Server v11.1.30 .Net Data Provider 是不是与 Visual Studio 2019 兼容?

用于用户管理的 ASP.NET Web 表单应用程序中的 Advantage Database Server (10.1)