sql >> Database >  >> RDS >> Sqlserver

Entity Framework Indexeert ALLE kolommen met externe sleutels

In EF Code First is de algemene reden waarom u een externe-sleutelrelatie zou modelleren de bevaarbaarheid tussen entiteiten. Overweeg een eenvoudig scenario van Country en City , met gretig laden gedefinieerd voor het volgende LINQ-statement:

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

Dit zou resulteren in een zoekopdracht in de trant van:

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

Zonder een Index op de refererende sleutel op City.CountryId , moet SQL de tabel Steden scannen om de steden voor het land te filteren tijdens een JOIN.

De FK-index heeft ook prestatievoordelen als rijen worden verwijderd uit de bovenliggende landentabel, aangezien referentiële integriteit de aanwezigheid van gekoppelde stadsrijen moet detecteren (of de FK ON CASCADE DELETE heeft gedefinieerd of niet).

TL;DR

Indexen op buitenlandse sleutels zijn aanbevolen , zelfs als u niet rechtstreeks op de externe sleutel filtert, is deze nog steeds nodig in Joins. De uitzonderingen hierop lijken nogal gekunsteld:

  • Als de selectiviteit van de refererende sleutel erg laag is, b.v. in het bovenstaande scenario, als 50% van ALLE steden in de landentabel in Japan zou zijn, dan zou de Index niet nuttig zijn.

  • Als je eigenlijk nooit door de relatie navigeert.

  • Als u nooit rijen uit de bovenliggende tabel verwijdert (of probeert bij te werken op de PK) .

Een aanvullende overweging voor optimalisatie is of de externe sleutel in de Clustered Index moet worden gebruikt van de onderliggende tabel (d.w.z. cluster Steden per land). Dit is vaak gunstig in parent:child-tabelrelaties waar het gebruikelijk is om alle onderliggende rijen voor de parent tegelijkertijd op te halen.



  1. Het selecteren van rijen geordend op een kolom en verschillend op een andere

  2. mysql fulltext MATCH,TEGEN 0 resultaten retourneren

  3. Hoe de NVL()-functie te gebruiken in Oracle

  4. MySQL Leg rijenlimiet uit