Проблема производительности LINQ-to-SQL для массовых вставок - PullRequest
4 голосов
/ 30 июня 2010

Я обнаружил проблему в своем приложении; в основном, одна подпрограмма подготавливает (много) данных, которые затем вставляются в мою локальную базу данных через контекст данных LINQ-to-SQL. Однако даже относительно скромное количество новых данных (100 000 строк) требует огромного количества времени для сохранения в базе данных при вызове SubmitChanges(). Однако в большинстве случаев приложению приходится сохранять от 200 000 до 300 000 строк.

Согласно профилировщику SQL Server, все сгенерированные запросы выглядят так, как показано ниже, и есть один для каждого элемента, который вставляет приложение.

exec sp_executesql N'INSERT INTO [dbo].[AdjectivesExpanded]([Adjective], [Genus], [Casus], [SingularOrPlural], [Kind], [Form])
VALUES (@p0, @p1, @p2, @p3, @p4, @p5)

SELECT CONVERT(BigInt,SCOPE_IDENTITY()) AS [value]',N'@p0 bigint,@p1 char(1),@p2 tinyint,@p3 bit,@p4 tinyint,@p5 nvarchar(4000)',@p0=2777,@p1='n',@p2=4,@p3=0,@p4=3,@p5=N'neugeborener'

Кто-нибудь имеет представление о том, как повысить производительность массовых вставок с помощью контекстов данных LINQ-to-SQL, в идеале без избавления от строго типизированного DataContext и возврата к рукописным запросам? как таковые? Плюс, есть небольшая возможность или пространство для настройки базовой базы данных. Во всяком случае, я мог бы отключить ограничения целостности, если это поможет.

Ответы [ 3 ]

3 голосов
/ 01 декабря 2011

Посмотрите на следующей странице простой обзор того, как изменить код для использования групповой вставки.

Вам просто нужно добавить (предоставленный) класс BulkInsert в ваш код, внести пару изменений, и вы увидите значительное улучшение производительности.

База знаний Mikes - BulkInserts с LINQ

2 голосов
/ 30 июня 2010

ORM обычно не очень хорошая идея для массовых операций. Я бы порекомендовал старомодную насыпную вставку, чтобы добиться максимальной производительности.

2 голосов
/ 30 июня 2010

Вы делаете что-то вроде этого:

foreach (var adjective in adjectives) {
    dataContext.AdjectivesExpanding.InsertOnSubmit(adjective)
    dataContext.SubmitChanges();
}

Или:

foreach (var adjective in adjectives) {
    dataContext.AdjectivesExpanding.InsertOnSubmit(adjective);
}
dataContext.SubmitChanges();

Если он похож на первый, я бы рекомендовал заменить его на что-то вроде второго. Каждый вызов SubmitChanges - это просмотр всех отслеживаемых объектов, чтобы увидеть, что изменилось.

В любом случае, я не уверен, что вставка этого объема элементов является хорошей идеей для Linq-to-Sql, поскольку он должен генерировать и оценивать SQL каждый раз.

Не могли бы вы написать скрипт хранимой процедуры и добавить его в качестве метода DataContext для дизайнера?

...