【发布时间】:2017-06-26 19:37:30
【问题描述】:
我正在测试服务代理外部激活器和基于轮询的客户端,代表它们各自的处理速度性能。
对于外部激活器,我构建了一个命令行应用程序,当某个表发生任何更改并写入同一个数据库时,它会收到通知。 exe里面的代码如下所示
private static void ProcessRequest()
{
using (var connection = new SqlConnection(ServiceConstant.ConnectionString))
{
connection.Open();
do
{
using (var tran = connection.BeginTransaction())
{
//Get a message from the queue
byte[] message = QueueProcessorUtil.GetMessage(ServiceConstant.QueueName, connection, tran, ServiceConstant.WaitforTimeout);
if (message != null)
{
MessageReceiving = true;
try
{
//Write it to the db
ProcessMessage(message);
}
catch (Exception ex)
{
logger.Write("Fail: " + ex);
}
tran.Commit();
}
else
{
tran.Commit();
MessageReceiving = false;
}
}
}
while (MessageReceiving);
}
}
当我向队列中插入 20 条消息时,插入所有消息的总持续时间约为 10ms
当我提取上面的 ProcessMessage 函数时,它将消息写入数据库到另一个单独的控制台应用程序,然后调用此函数 20 次,如下所示,这次大约需要 50ms
class Program
{
static void Main(string[] args)
{
for (var i = 1; i <= 20; i++)
{
string message = "mm";
ProcessMessaage(message);
}
}
}
ProcessMessage函数
string sql = @"INSERT INTO [Workflow].[dbo].[TestOrderLog]([OrderId],[RecordTime])
VALUES (@orderId, GETDATE()) SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["SqlConnection"].ToString()))
using (SqlCommand com = new SqlCommand(sql, con))
{
con.Open();
com.CommandType = CommandType.Text;
com.Parameters.AddWithValue("@orderId", 1);
try
{
var result = com.ExecuteScalar();
var id = (result != null) ? Convert.ToInt32(result) : 0;
}
catch (Exception ex)
{
throw ex;
}
con.Close();
}
我不明白也很惊讶,尽管在外部激活器代码的循环中存在昂贵的处理块(查询消息),但编写 db 比在控制台应用程序代码中编写纯循环要快。
为什么在循环中纯插入比在外部激活器 exe 实例的代码中插入要慢?
旁注,在 EAService.config 文件中,<Concurrency min="1" max="1" />
【问题讨论】:
-
好的,请解释您的要求。您是说在控制台应用程序代码中编写 db 比编写纯循环需要更快吗?那么写入数据库比使用控制台应用程序更快吗?不知道这里的问题是什么。
-
@Namphibian 实际上我写了所有东西,外部激活器触发 exe,此代码中的循环(
ProcessRequest函数)然而,以某种方式比控制台应用程序更快地插入到 db。如果您检查间隔,每毫秒插入第一个记录 4 到 8 条记录,另一方面,为第二种情况仅插入一条记录需要 3 毫秒。这到底是怎么发生的?上面第一个代码中的循环也查询到了数据库的第一位。 -
阅读 O Notation 并尝试找出哪个 O 系数较低。
-
据我所知,步数越少,算法越快,所以,第二个应该更快,但让我计算一下O因子看看。
-
等一下,你在第一个而不是第二个使用事务?
标签: c# sql-server sqlconnection service-broker