【发布时间】:2015-12-01 07:57:12
【问题描述】:
我有一个包含 2 列的简单表格(一列是 identity,另一列是 char 列):
CREATE TABLE [dbo].[tbl]
(
[id] [INT] IDENTITY(1,1) NOT NULL,
[col] [CHAR](32) NULL,
CONSTRAINT [PK_tbl] PRIMARY KEY CLUSTERED ([id] ASC)
)
我们有一个函数可以执行一些长时间运行的操作。这是一些伪代码:
void doWork()
{
using(context)
{
doLongPart1(context);
...
doLongPartN(context);
}
}
现在我正在尝试使用各自的上下文将它们隔离在单独的任务中。但令人惊讶的是,有任务的版本比没有任务的版本要花更多的时间。我在这里插入10,000 行。时间是:~54000ms 没有任务的版本和~57000ms 有任务的版本。我正在使用EF6.0,这是要重现的完整代码:
初始版本
static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();
var c = 10000;
var c1 = new TestEntities();
for (int i = 1; i < c / 2; i++)
c1.tbls.Add(new tbl { col = i.ToString() });
c1.SaveChanges();
var c2 = new TestEntities();
for (int i = c / 2; i < c; i++)
c2.tbls.Add(new tbl { col = i.ToString() });
c2.SaveChanges();
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
带任务的版本
static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();
var c = 10000;
Task[] tasks = new Task[2];
tasks[0] = Task.Run(() =>
{
var c1 = new TestEntities();
for (int i = 1; i < c / 2; i++)
c1.tbls.Add(new tbl { col = i.ToString() });
c1.SaveChanges();
});
tasks[1] = Task.Run(() =>
{
var c2 = new TestEntities();
for (int i = c / 2; i < c; i++)
c2.tbls.Add(new tbl { col = i.ToString() });
c2.SaveChanges();
});
Task.WaitAll(tasks);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
我也尝试过通过存储过程来做到这一点:
CREATE PROC spTbl @s CHAR(32)
AS
INSERT INTO dbo.tbl (col)
VALUES (@s)
和代码:
static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();
var c = 10000;
Task[] tasks = new Task[2];
tasks[0] = Task.Run(() =>
{
var c1 = new TestEntities();
for (int i = 1; i < c / 2; i++)
c1.spTbl(i.ToString());
});
tasks[1] = Task.Run(() =>
{
var c2 = new TestEntities();
for (int i = c / 2; i < c; i++)
c2.spTbl(i.ToString());
});
Task.WaitAll(tasks);
}
我什至尝试过配置 SQL Server:
sp_configure 'show advanced options', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
sp_configure 'max degree of parallelism', 8;
GO
RECONFIGURE WITH OVERRIDE;
GO
但是对我没有任何作用。谁能指出我正确的方向?
【问题讨论】:
-
连接到数据库的开销和/或表上的锁很可能与此有关。
-
@LasseV.Karlsen,我正在与 DBA 核对这一点,很快就会通知你。我也会检查选择。选择不应该给我带来不同吗?
-
好的,事实证明我刚刚达到了我的 Sql 引擎的最大值,所以并行执行没有区别。两人都在以最大可能的速度工作。此外,在数据库级别根本没有锁..
标签: c# entity-framework sql-server-2012 task-parallel-library