Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Entity Framework Indizierung ALLER Fremdschlüsselspalten

In EF Code First ist der allgemeine Grund, warum Sie eine Fremdschlüsselbeziehung modellieren, die Navigierbarkeit zwischen Entitäten. Stellen Sie sich ein einfaches Szenario von Country vor und City , wobei Eager Loading für die folgende LINQ-Anweisung definiert ist:

var someQuery = 
   db.Countries
     .Include(co => co.City)
     .Where(co => co.Name == "Japan")
     .Select(...);

Dies würde zu einer Abfrage in der Art von:

führen
SELECT *
FROM Country co
INNER JOIN City ci
  ON ci.CountryId = co.ID
WHERE co.Name = 'Japan';

Ohne einen Index auf dem Fremdschlüssel auf City.CountryId , muss SQL die Cities-Tabelle scannen, um die Städte für das Land während eines JOINs zu filtern.

Der FK-Index hat auch Leistungsvorteile, wenn Zeilen gelöscht werden aus der übergeordneten Country-Tabelle, da die referenzielle Integrität das Vorhandensein von verknüpften City-Zeilen erkennen muss (ob der FK ON CASCADE DELETE hat definiert oder nicht).

TL;DR

Indizes für Fremdschlüssel sind empfohlen , auch wenn Sie nicht direkt nach dem Fremdschlüssel filtern, wird er dennoch in Joins benötigt. Die Ausnahmen hiervon scheinen recht konstruiert zu sein:

  • Ist die Selektivität des Fremdschlüssels sehr gering, z. Wenn im obigen Szenario 50 % ALLER Städte in der Ländertabelle in Japan liegen würden, wäre der Index nicht hilfreich.

  • Wenn Sie nicht wirklich jemals durch die Beziehung navigieren.

  • Wenn Sie niemals Zeilen aus der übergeordneten Tabelle löschen (oder versuchen, den PK zu aktualisieren) .

Eine weitere Optimierungsüberlegung ist, ob der Fremdschlüssel im Clustered Index verwendet werden soll der untergeordneten Tabelle (d. h. Cluster Städte nach Land). Dies ist häufig in Eltern-Kind-Tabellenbeziehungen von Vorteil, bei denen es üblich ist, alle untergeordneten Zeilen für die übergeordnete Tabelle gleichzeitig abzurufen.