EF 코드 우선 모든 문자열에 대해 nvarchar (max)를 사용합니다. 이로 인해 쿼리 성능이 저하됩니까?


29

Entity Framework Code First를 사용하여 생성 한 데이터베이스가 있습니다. 앱이 작동하고 일반적으로 Code First가 할 수있는 일에 매우 만족합니다. 필자는 우선 프로그래머이고 DBA는 두 번째입니다. C #에서 데이터베이스가 무엇을 원하는지 자세히 설명하기 위해 DataAttributes에 대해 읽고 있습니다. 내 질문은 : nvarchar(max)문자열을 내 테이블에 넣으면 어떤 형벌을 먹을 것 입니까 (아래 예 참조)?

이 특정 테이블에는 몇 개의 열이 있습니다. C #에서는 다음과 같이 정의됩니다.

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Message { get; set; }
    public string Source { get; set; }
    public DateTime Generated { get; set; }
    public DateTime Written { get; set; }

이름, 소스, 생성 및 작성을 기반으로 쿼리 및 / 또는 정렬 할 것으로 예상합니다. 이름과 소스는 0-50 자 길이, 때로는 최대 150 자까지 예상합니다.이 테이블은 아주 작게 시작 (100 만 행 미만)하지만 시간이 지남에 따라 크게 증가합니다 (> 1m 행). 분명히 메시지는 작거나 클 수 있으며 쿼리되지 않을 것입니다.

내가 알고 싶은 것은 이름과 소스 열이 nvarchar(max)150 자보다 클 것으로 예상하지 않을 때 정의되는 성능 저하가 있습니까?


5
[MaxLength]또는 [StringLength]속성 을 적용해야하는 것 같습니다 . 너무 넓은 열 몇 가지 추가 부정적인 요인은 여기 @ PaulWhite의 대답에 언급
마틴 스미스

3
, varchar(max)어디서나 사용하면 성능이 저하 됩니다.하지 마십시오! 사용하여 적절한 사용 - 데이터 유형을 varchar(max) 당신이하면 정말 8000 개 이상의 문자를 필요로한다! (저는 사람의 이름이나 전자 우편을 본 적이 없습니다!)- VARCHAR (n) 사용의 요점은 무엇입니까 ?를 참조하십시오 . 더 많은 정보
marc_s

@marc_s 훌륭한 링크. 성능이 저하된다는 것을 알고 있습니다. SQL로 자신의 테이블을 정의 할 때 varchar (n)을 사용합니다. 내 질문은 성능에 얼마나 많은 영향을 미치는지에 관한 것이 었습니다 (명시 적으로 명확하지 않은 게시 된 것으로 알고 있지만).
Nate

답변:


24

더 큰 nvarchar (최대) 데이터 항목 (8000 바이트 이상)은 텍스트 저장소로 넘겨지며 추가 I / O가 필요합니다. 작은 항목은 행에 저장됩니다. 이 동작을 제어하는 ​​옵션이 있습니다 . 자세한 내용 은이 MSDN 문서 를 참조하십시오.

행에 저장된 경우 상당한 I / O 성능 오버 헤드가 없습니다. 데이터 유형을 처리하는 데 추가 CPU 오버 헤드가있을 수 있지만 이는 사소한 것일 수 있습니다.

그러나 nvarchar (최대) 열을 필요하지 않은 데이터베이스 주위에 두는 것은 다소 열악한 형태입니다. 약간의 성능 오버 헤드가 있으며 종종 데이터 크기가 데이터 테이블을 이해하는 데 도움이됩니다. 예를 들어, 너비가 50 또는 100자인 varchar 열은 설명 또는 자유 텍스트 필드 일 수 있습니다 (예 : 10- 20 문자 링은 코드 일 가능성이 높습니다. 이와 같은 가정을 통해 데이터베이스에서 자주 추론해야하는 의미에 놀랄 것입니다.

제대로 지원되지 않거나 문서화 된 레거시 시스템에서와 같이 데이터웨어 하우징에서 작업하는 것은 이해하기 쉬운 데이터베이스 스키마를 갖는 것이 매우 중요합니다. 데이터베이스를 응용 프로그램의 레거시로 생각하면 데이터베이스를 상속받을 사람들에게 친절하십시오.


18

이것은 특정 질문에 대한 답변은 아니지만 먼저 질문을 할 필요가 없습니다. C # 모델 클래스에서 문자열 변수의 길이를 설정하면 Entity Framework가 다음과 같은 SQL을 생성 할 수 있습니다. nvarchar(50)대신 고정 길이 nvarchar 유형 (예 :)을 사용합니다 nvarchar(max).

예를 들어,

public string Name { get; set; }

당신이 사용할 수있는:

[StringLength(50)]
public string Name { get; set; }

원하는 경우 다음과 같이 유형을 varchar대신 대신 강제로 지정할 수도 nvarchar있습니다.

[Column(TypeName = "VARCHAR")]
[StringLength(50)]
public string Name { get; set; }

출처 : https://stackoverflow.com/questions/7341783/entity-framework-data-annotations-set-stringlength-varchar/7341920


2
EF Core가 유형과 길이 설정을 동시에 지원한다는 것을 알기 위해이 답변을 찾았 varchar(50)지만 EF 6에는이 답변의 내용이 필요합니다.
Sinjai

9

가장 큰 관심사 색인. BOL에서 :

큰 객체 (LOB) 데이터 타입이다 열 ntext, text, varchar(max), nvarchar(max), varbinary(max), xml, 또는 image인덱스 키위한 열로서 지정 될 수 없다.

제대로 색인을 생성 할 수 없으면 쿼리 속도가 느려집니다. 그리고 데이터 무결성 관점에서 볼 nvarchar(max)때 제한을 지정하는 것보다 더 나쁜 데이터를 필드에 넣을 수 있습니다.


9

예,에 매핑 string할 때 기본 EF 동작 nvarchar(max)이 좋지 않습니다. EF 6에서는 고유 한 기본 규칙으로이 동작을 재정의하기 위해 고유 한 사용자 지정 규칙을 추가 할 수 있습니다.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<string>()
        .Configure(s => s.HasMaxLength(200).HasColumnType("varchar") );

    base.OnModelCreating(modelBuilder);
}

OnModelCreating위와 같이 재정의 하면 모든 문자열의 기본 매핑이로 변경됩니다 varchar(200).


1
이 1.0 EF 코어에서 작동하지 않습니다
시튜 조셉 Olugbenga에게

the default EF behavior in mapping string to nvarchar(max) is not good이것은 당신의 일반화 된 의견 인 것 같습니다. 왜 이것이 좋지 않은지 설명 할 수 있습니까? 아니면 EF는 여러 언어로 작업해야하는 비즈니스 응용 프로그램의 프레임 워크가 아니라고 생각합니까? 데이터베이스에서 여러 언어를 처리하기 위해 원하는 열 유형이기 때문입니다.
Matthias Burger

1
@MatthiasBurger nvarchar (max)는 특히 복제 된 환경에서 성능이 끔찍합니다. 일반적인 의견이 아니며 잘 알려진 사실입니다.
user2966445

@ user2966445 죄송합니다, 오해가 있다고 생각합니다 :) 확실히, max끔찍합니다. 그러나 여러 언어 (및 다른 문자 집합)를 처리하려면 nvarchar잘못 사용해야 합니까?
Matthias Burger

@MatthiasBurger 맞습니다. 다른 문자 세트에 nvarchar를 사용하십시오. 그러나이 전체 게시물은 nvarchar와 varchar의 사용이 아니라 성능과 필드 길이에 관한 것입니다.
user2966445
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.