it-swarm.com.de

EF Code First verwendet nvarchar (max) für alle Zeichenfolgen. Beeinträchtigt dies die Abfrageleistung?

Ich habe einige Datenbanken mit Entity Framework Code First erstellt. Die Apps funktionieren und im Allgemeinen bin ich ziemlich zufrieden mit dem, was Code First mir ermöglicht. Ich bin zuerst ein Programmierer und notgedrungen ein DBA. Ich lese über DataAttributes, um in C # näher zu beschreiben, was die Datenbank tun soll. und meine Frage ist: welche Strafe werde ich essen, wenn ich diese nvarchar(max) Strings in meiner Tabelle habe (siehe Beispiel unten)?

Diese spezielle Tabelle enthält mehrere Spalten. in C # sind sie als solche definiert:

    [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; }

Ich erwarte, nach Name, Quelle, Generiert und Geschrieben abzufragen und/oder zu sortieren. Ich erwarte, dass Name und Quelle 0-50 Zeichen lang sind, gelegentlich bis zu 150. Ich erwarte, dass diese Tabelle ziemlich klein anfängt (<100.000 Zeilen), aber im Laufe der Zeit erheblich wächst (> 1 Mio. Zeilen). Offensichtlich kann die Nachricht klein oder groß sein und wird wahrscheinlich nicht abgefragt.

Was ich wissen möchte, gibt es einen Leistungseinbruch für meine Namen- und Quellenspalten, die als nvarchar(max) definiert werden, wenn ich nie erwarte, dass sie größer als 150 Zeichen sind?

29
Nate

Größere nvarchar (max) Datenelemente (über 8000 Byte oder so) werden in den Textspeicher übertragen und erfordern zusätzliche E/A. Kleinere Artikel werden in einer Reihe gespeichert. Es gibt Optionen, die dieses Verhalten steuern. Weitere Informationen finden Sie in diesem MSDN-Artikel .

Wenn in Reihe gespeichert, entsteht kein erheblicher Aufwand für die E/A-Leistung. Bei der Verarbeitung des Datentyps kann zusätzlicher CPU-Overhead anfallen, der jedoch wahrscheinlich geringfügig ist.

Es ist jedoch eher schlecht, nvarchar (max) -Spalten in der Datenbank liegen zu lassen, wo sie nicht benötigt werden. Es hat einige Leistungsaufwand und oft sind Datengrößen sehr hilfreich für das Verständnis einer Datentabelle - zum Beispiel ist eine 50 oder 100 Zeichen breite Varchar-Spalte wahrscheinlich eine Beschreibung oder ein Freitextfeld, in dem Eine, die (sagen wir) 10-20 Zeichen enthält, ist wahrscheinlich ein Code. Sie wären überrascht, wie viel Bedeutung man durch solche Annahmen häufig aus einer Datenbank ableiten muss.

Wenn Sie im Data Warehousing arbeiten, so oft wie nicht auf schlecht unterstützten oder dokumentierten Legacy-Systemen, ist ein leicht verständliches Datenbankschema sehr wertvoll. Wenn Sie die Datenbank als das Vermächtnis der Anwendung betrachten, versuchen Sie, nett zu den Personen zu sein, die sie von Ihnen erben werden.

Dies beantwortet zwar nicht Ihre spezifische Frage, kann jedoch dazu führen, dass Sie die Frage zunächst nicht stellen müssen: Es ist möglich, eine Länge für Ihre Zeichenfolgenvariablen in Ihrer C # -Modellklasse festzulegen, wodurch Entity Framework SQL generiert verwendet einen nvarchar-Typ fester Länge (z. B. nvarchar(50)) anstelle von nvarchar(max).

Zum Beispiel anstelle von:

public string Name { get; set; }

Sie können verwenden:

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

Falls gewünscht, können Sie den Typ auch wie folgt erzwingen: varchar anstelle von nvarchar:

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

Quelle: https://stackoverflow.com/questions/7341783/entity-framework-data-annotations-set-stringlength-varchar/734192

18
Jon Schneider

Indizierung der größten Sorge. Von BOL:

Spalten der Datentypen Large Object (LOB) ntext, text, varchar(max), nvarchar(max), varbinary(max), xml oder image können nicht als Schlüsselspalten für einen Index angegeben werden.

Wenn Sie nicht richtig indizieren können, werden Sie langsame Abfragen haben. Aus Sicht der Datenintegrität können mit nvarchar(max) mehr fehlerhafte Daten in ein Feld eingefügt werden, als dies bei der Angabe des Grenzwerts der Fall wäre.

9
HLGEM

Ja, das Standard-EF-Verhalten bei der Zuordnung von string zu nvarchar(max) ist nicht gut. In EF 6 können Sie Ihre eigene benutzerdefinierte Konvention hinzufügen, um dieses Verhalten mit Ihrer bevorzugten Standardzuordnung zu überschreiben.

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

    base.OnModelCreating(modelBuilder);
}

Durch Überschreiben von OnModelCreating wie oben wird die Standardzuordnung für alle Zeichenfolgen in varchar(200) geändert.

9
Paul