У меня есть база данных 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)
Итак, как вы только что поняли,
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 );
, чтобы определить, существует ли он уже (и после этого получить идентификатор).
Производительность очень плохо, как это!
Я ' Мы пытались сделать выбор с помощью слова WHERE
, чтобы избежать загрузки каждой строки TableParameter
, но производительность хуже!
Как я могу улучшить производительность шага 1?
Для шага 2 производительность классического INSERT
по-прежнему оставляет желать лучшего. Я собираюсь попробовать SqlBulkCopy
.
Как я могу улучшить производительность шага 2?
EDITED
Я пробовал с процедурой хранения:
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
У меня все та же производительность ... :-( (неприемлемо)