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

时间:2013-06-05 16:50:25

标签: .net performance database-connection advantage-database-server

我正在使用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

1 个答案:

答案 0 :(得分:2)

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