У меня есть база данных 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 );
, чтобы определить, существует ли она уже (и после получения идентификатора).
Производительность очень плохая, как это!
Я пытался сделать выбор с помощью слова 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
У меня все еще та же производительность ... :-( (не приемлемо)