Очень низкая производительность для пакетной вставки с SQL Server CE 4.0 и Entity Framework 4.2 - PullRequest
8 голосов
/ 24 января 2012

Я вставляю много данных в SQL Server CE 4.0, используя Entity Framework 4.2 (сначала код), и производительность по сравнению с прямой вставкой SQL просто ужасна.

Модель очень проста:

public class DocMember
{
    public DocMember() { this.Items = new List<DocItem>(); }

    public int Id { get; set; }

    public string Name { get; set; }
    public string MemberType { get; set; }
    public string AssemblyName { get; set; }

    public virtual IList<DocItem> Items { get; set; }
}

public class DocItem
{
    public int Id { get; set; }
    public DocMember Member { get; set; }
    public string PartType { get; set; }
    public string PartName { get; set; }
    public string Text { get; set; }
}

У меня есть 2623 DocMembers и всего 7747 DocItems для вставки, и я получаю следующее время выполнения:

With SQL: 00:00:02.8
With EF:  00:03:02.2

Я могу понять, что с EF есть некоторые издержки, но это в 65 раз медленнее, чем в SQL!

Возможно, в моем коде есть проблема, но она довольно проста, и я не вижу, что может быть не так:

    private TimeSpan ImportMembersEF(IList<DocMember> members)
    {
        using (var db = new DocEntities())
        {
            db.Database.CreateIfNotExists();

            var sw = Stopwatch.StartNew();
            foreach (var m in members)
            {
                db.Members.Add(m);
            }

            db.SaveChanges();
            sw.Stop();
            return sw.Elapsed;
        }
    }

Я также пытался звонить SaveChanges для каждого вставленного элемента или каждые 100 или 200 элементов, но безрезультатно (на самом деле это еще хуже).

Есть ли способ повысить производительность или мне нужно использовать SQL для пакетной вставки?


РЕДАКТИРОВАТЬ: для полноты, вот код для вставки SQL: http://pastebin.com/aeaC1KcB

Ответы [ 2 ]

6 голосов
/ 24 января 2012

Вы можете использовать мою библиотеку SqlCeBulkCopy для загрузки объемных данных, она имитирует API SqlBulkCopy: http://sqlcebulkcopy.codeplex.com

1 голос
/ 24 января 2012

Это медленно, потому что это не пакетная вставка.

Когда вы вставляете с использованием идентификатора в БД, он должен выбрать идентификатор результата после каждого элемента, который будет присвоен модели.Это делает его очень медленным.

Ваш специальный SQL не выбирает идентификатор, поэтому при пакетировании вы можете отправить все операторы одновременно.

Альт, написанный с помощью NHibernate:

http://www.philliphaydon.com/2011/09/the-benefits-of-letting-the-orm-generate-the-identity-part-1/

Я писал об использовании сгенерированных ORM идентификаторов против идентификаторов, сгенерированных SQL.

...