我有一个这样设计的 SQL Server 数据库:
TableParameter
Id (int, PRIMARY KEY, IDENTITY)
Name1 (string)
Name2 (string, can be null)
Name3 (string, can be null)
Name4 (string, can be null)
TableValue
Iteration (int)
IdTableParameter (int, FOREIGN KEY)
Type (string)
Value (decimal)
因此,正如您刚刚了解的那样,TableValue
与TableParameter
.
TableParameter
就像一个多维字典。
TableParameter
应该有很多行(超过 300,000 行)
在我的 c# 客户端程序中,我必须在每个Compute()
函数之后填充这个数据库:
for (int iteration = 0; iteration < 5000; iteration++)
{
Compute();
FillResultsInDatabase();
}
在FillResultsInDatabase()
方法上,我必须:
- 检查我的参数的标签是否已经存在于
TableParameter
. 如果它不存在,我必须插入一个新的。 - 我必须在
TableValue
第1步需要很长时间!我将所有表加载到TableParameter
IEnumerable 属性中,然后为每个参数创建一个
.FirstOfDefault( x => x.Name1 == item.Name1 &&
x.Name2 == item.Name2 &&
x.Name3 == item.Name3 &&
x.Name4 == item.Name4 );
为了检测它是否已经存在(以及之后获取id)。
这样的表现非常糟糕!
我试图用WHERE
word 进行选择以避免加载每一行TableParameter
但性能更差!
如何提高第 1 步的性能?
对于第 2 步,classic 的性能仍然很差INSERT
。我要试试SqlBulkCopy
。
如何提高第 2 步的性能?
已编辑
我尝试过使用 Store Procedure :
CREATE PROCEDURE GetIdParameter
@Id int OUTPUT,
@Name1 nvarchar(50) = null,
@Name2 nvarchar(50) = null,
@Name3 nvarchar(50) = null
AS
SELECT TOP 1 @Id = Id FROM TableParameter
WHERE
TableParameter.Name1 = @Name1
AND
(@Name2 IS NULL OR TableParameter.Name2= @Name2)
AND
(@Name3 IS NULL OR TableParameter.Name3 = @Name3)
GO
CREATE PROCEDURE CreateValue
@Iteration int,
@Type nvarchar(50),
@Value decimal(32, 18),
@Name1 nvarchar(50) = null,
@Name2 nvarchar(50) = null,
@Name3 nvarchar(50) = null
AS
DECLARE @IdParameter int
EXEC GetIdParameter @IdParameter OUTPUT,
@Name1, @Name2, @Name3
IF @IdParameter IS NULL
BEGIN
INSERT TablePArameter (Name1, Name2, Name3)
VALUES
(@Name1, @Name2, @Name3)
SELECT @IdParameter= SCOPE_IDENTITY()
END
INSERT TableValue (Iteration, IdParamter, Type, Value)
VALUES
(@Iteration, @IdParameter, @Type, @Value)
GO
我仍然有相同的表现...... :-((不可接受)