SORU
18 Aralık 2009, Cuma


Varlık Çerçevesi nesnelerin 1000'ler oluştururken? ne zaman arasam SaveChanges() (alma sırasında gibi)

Her çalışma kayıtları 1000 olacak bir ithalat çalıştırıyorum. Sadece varsayımlar üzerine bazı onay arıyor:

Bunlardan hangisi en mantıklı:

  1. SaveChanges() AddToClassName() Her bir arama çalıştırın.
  2. SaveChanges() Her çalıştırınnAddToClassName() telefon numarası.
  3. SaveChanges() sonra çalıştırıntümAddToClassName() arama.

İlk seçenek, muhtemelen yavaş değil mi? Bellekte EF nesneleri analiz etmek gerekir bu yana, vb SQL oluşturmak.

Ben ikinci seçeneği deneyin. SaveChanges() çağrı yakalamak ve sadece kaybetmek şal edebiliriz bu yana her iki dünyanın en iyi olduğunu varsayalımneğer bunlardan biri başarısız olursa kayıtların sayısını bir anda. Belki Listesi<^ her toplu saklayın . . Eğer SaveChanges() çağrı başarılı olursa, liste kurtulmak. Eğer başarısız olursa, kayıtlara geçeyim.

Son seçenek muhtemelen her EF nesne SaveChanges() kadar bellek gerekir beri çok yavaş sonu olur. Ve eğer kaydetme başarısız olan hiçbir şey kararlı olacak, değil mi?

CEVAP
18 Aralık 2009, Cuma


Önce emin olmak için test ediyorum. Performans o kadar da kötü olmak zorunda değil.

Eğer tek bir işlemle tüm satırları girmeniz gerekiyorsa, AddToClassName sınıf tüm sonra Ara. Eğer satır bağımsız olarak girilebilir, her satır sonra değişiklikleri kaydedin. Veritabanı kıvamı önemlidir.

Sevmiyorum ikinci seçenek. Sistem ithalat yaptım ve 1 kötü, çünkü 1000, 10 satır düşüş olacaksa benim için kafa karıştırıcı (son kullanıcı açısından) olurdu. 10 almak için deneyebilirsiniz ve eğer başarısız olursa, tek tek deneyin ve oturum açın.

Eğer Test uzun zaman alır. Yazmayın ''. Akat Bunu henüz bilmiyorsun. Aslında bir sorun değil sadece, (marc_s) başka bir çözüm düşünüyorum.

EDİT

Bazı testler (miliseconds zaman) yaptım:

10000 satır:

() SaveChanges 1 satır:18510,534 . sonra ^/^ br . () SaveChanges sonra 100 satır:4350,3075

50000 satır:

() SaveChanges 1 satır:78496,929 . sonra ^/^ br . () SaveChanges 500 satır sonra:22302,2835

Aslında daha sonra n satır sonra işlemek için daha hızlı olduğu için.

Benim önerim şudur:

  • () SaveChanges n satır sonra.
  • Eğer başarısız bir taahhüt varsa, bir tane hatalı satırı bulmaya çalışın.

Test sınıfları:

TABLO:

CREATE TABLE [dbo].[TestTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [SomeInt] [int] NOT NULL,
    [SomeVarchar] [varchar](100) NOT NULL,
    [SomeOtherVarchar] [varchar](50) NOT NULL,
    [SomeOtherInt] [int] NULL,
 CONSTRAINT [PkTestTable] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

Sınıf:

public class TestController : Controller
{
    //
    // GET: /Test/
    private readonly Random _rng = new Random();
    private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    private string RandomString(int size)
    {
        var randomSize = _rng.Next(size);

        char[] buffer = new char[randomSize];

        for (int i = 0; i < randomSize; i  )
        {
            buffer[i] = _chars[_rng.Next(_chars.Length)];
        }
        return new string(buffer);
    }


    public ActionResult EFPerformance()
    {
        string result = "";

        TruncateTable();
        result = result   "SaveChanges() after 1 row:"   EFPerformanceTest(10000, 1).TotalMilliseconds   "<br/>";
        TruncateTable();
        result = result   "SaveChanges() after 100 rows:"   EFPerformanceTest(10000, 100).TotalMilliseconds   "<br/>";
        TruncateTable();
        result = result   "SaveChanges() after 10000 rows:"   EFPerformanceTest(10000, 10000).TotalMilliseconds   "<br/>";
        TruncateTable();
        result = result   "SaveChanges() after 1 row:"   EFPerformanceTest(50000, 1).TotalMilliseconds   "<br/>";
        TruncateTable();
        result = result   "SaveChanges() after 500 rows:"   EFPerformanceTest(50000, 500).TotalMilliseconds   "<br/>";
        TruncateTable();
        result = result   "SaveChanges() after 50000 rows:"   EFPerformanceTest(50000, 50000).TotalMilliseconds   "<br/>";
        TruncateTable();

        return Content(result);
    }

    private void TruncateTable()
    {
        using (var context = new CamelTrapEntities())
        {
            var connection = ((EntityConnection)context.Connection).StoreConnection;
            connection.Open();
            var command = connection.CreateCommand();
            command.CommandText = @"TRUNCATE TABLE TestTable";
            command.ExecuteNonQuery();
        }
    }

    private TimeSpan EFPerformanceTest(int noOfRows, int commitAfterRows)
    {
        var startDate = DateTime.Now;

        using (var context = new CamelTrapEntities())
        {
            for (int i = 1; i <= noOfRows;   i)
            {
                var testItem = new TestTable();
                testItem.SomeVarchar = RandomString(100);
                testItem.SomeOtherVarchar = RandomString(50);
                testItem.SomeInt = _rng.Next(10000);
                testItem.SomeOtherInt = _rng.Next(200000);
                context.AddToTestTable(testItem);

                if (i % commitAfterRows == 0) context.SaveChanges();
            }
        }

        var endDate = DateTime.Now;

        return endDate.Subtract(startDate);
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • chickenby

    chickenby

    2 HAZİRAN 2008
  • bored before i even began

    bored before

    30 Mart 2009
  • TVNorge

    TVNorge

    5 EKİM 2006