Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Indicizzazione di Entity Framework TUTTE le colonne di chiavi esterne

In EF Code First, il motivo generale per cui si dovrebbe modellare una relazione di chiave esterna è per la navigabilità tra entità. Considera un semplice scenario di Country e City , con caricamento ansioso definito per la seguente istruzione LINQ:

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

Ciò risulterebbe in una query simile a:

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

Senza un indice sulla chiave esterna su City.CountryId , SQL dovrà scansionare la tabella Cities per filtrare le città per il Paese durante un JOIN.

L'indice FK avrà anche vantaggi in termini di prestazioni se le righe vengono eliminate dalla tabella Country padre, poiché l'integrità referenziale dovrà rilevare la presenza di eventuali righe City collegate (se l'FK ha ON CASCADE DELETE definito o meno).

TL;DR

Indici su chiavi esterne sono consigliato , anche se non filtri direttamente sulla chiave esterna, sarà comunque necessaria in Join. Le eccezioni a questo sembrano essere abbastanza artificiose:

  • Se la selettività della chiave esterna è molto bassa, ad es. nello scenario precedente, se il 50% di TUTTE le città nella tabella dei paesi fosse in Giappone, l'indice non sarebbe utile.

  • Se in realtà non navighi mai attraverso la relazione.

  • Se non elimini mai righe dalla tabella padre (o tenti l'aggiornamento sulla PK) .

Un'ulteriore considerazione per l'ottimizzazione è se utilizzare la chiave esterna nell'Clustered Index della tabella figlio (ovvero cluster Cities by Country). Questo è spesso vantaggioso nelle relazioni parent :child table in cui è normale recuperare tutte le righe figlio per il genitore contemporaneamente.