나는 그것을 확인하기 위해 먼저 테스트 할 것입니다. 성능이 그렇게 나쁠 필요는 없습니다.
하나의 트랜잭션에 모든 행을 입력해야하는 경우 모든 AddToClassName 클래스 다음에 호출하십시오. 행을 독립적으로 입력 할 수있는 경우 모든 행 후에 변경 사항을 저장합니다. 데이터베이스 일관성이 중요합니다.
두 번째 옵션이 마음에 들지 않습니다. 시스템으로 가져 오기를 수행하면 (최종 사용자 관점에서) 혼란스럽고 1이 나쁘기 때문에 1000 행 중 10 행이 감소합니다. 10 개 가져 오기를 시도 할 수 있으며 실패 할 경우 하나씩 시도한 다음 기록합니다.
시간이 오래 걸리는지 테스트하십시오. '적절하게'쓰지 마십시오. 당신은 아직 그것을 모릅니다. 실제로 문제가되는 경우에만 다른 솔루션 (marc_s)을 생각하십시오.
편집하다
몇 가지 테스트를 수행했습니다 (밀리 초 단위).
10000 개의 행 :
1 행 이후 SaveChanges () : 18510,534
100 행 이후
SaveChanges () : 4350,3075 10000 행 이후 SaveChanges () : 5233,0635
50000 행 :
1 행 이후 SaveChanges () : 78496,929
500 행 이후
SaveChanges () : 22302,2835 50000 행 이후 SaveChanges () : 24022,8765
따라서 실제로는 결국 n 행 이후에 커밋하는 것이 더 빠릅니다.
내 추천은 다음과 같습니다.
- n 행 이후 SaveChanges ().
- 하나의 커밋이 실패하면 하나씩 시도하여 잘못된 행을 찾습니다.
테스트 클래스 :
표:
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]
수업:
public class TestController : Controller
{
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);
}
}