L'ho fatto su indici specifici prima d'ora, per aiutare spesso a eseguire query pesanti. In effetti ciò che hanno fatto è creare più indici cluster: quando uno di questi indici viene utilizzato per trovare le righe non è necessario alcun lavoro aggiuntivo cercando il resto dei dati nell'indice cluster reale (o l'heap se non esiste un indice cluster reale) .
è una strategia sensata?
Per alcuni indici dove necessario per supportare determinati schemi di query, certamente sì.
Ma per fare questo con tutti gli indici, direi proprio di no.
Sarà uno spreco di spazio da fare dove non effettivamente necessario e rallenterà in modo significativo inserimenti / aggiornamenti. Potrebbe rallentare il numero di query di lettura che aiuta anche, poiché ogni pagina di indice contiene meno record, quindi qualsiasi query che deve fare riferimento a una parte dell'indice per il filtro ma che non utilizza tutte le altre colonne dovrà accedere a più pagine. Questo renderà il tuo database più affamato di memoria: quelle pagine dovranno essere caricate nel pool di buffer, espellendo potenzialmente altre pagine utili se la memoria è insufficiente. Se la compressione viene utilizzata su quegli indici per tentare di mitigare l'effetto sui requisiti di archiviazione e memoria, verrà invece applicato un carico aggiuntivo alle CPU.
poiché l'accesso avviene tramite un ORM che per impostazione predefinita (ma non sempre) recupera tutte le colonne
Questo è un modello comune con un utilizzo scarsamente ottimizzato di un ORM (o solo ORM ingenui) e in questi casi ho visto il consulente di indice di SQL Server (e strumenti di terze parti simili) suggerire indici con molte INCLUDE
colonne d, quindi sarei d'accordo con il tuo suggerimento che questo è il motivo per cui gli indici sono stati creati in questo modo.
Ma sebbene possa rendere tutte queste query leggermente più veloci e alcune significativamente più veloci, sospetto che in molti casi qualsiasi vantaggio sia così piccolo da non valere la memoria aggiuntiva richiesta dal tuo comune set di lavoro, lo spazio su disco e l'IO tra disco e memoria.
Ricorda inoltre che l'ORM potrebbe non selezionare tutte le colonne di tutte le tabelle toccate da una query, quindi il vantaggio potrebbe essere valido solo per la destinazione principale della richiesta corrente e gli indici più grandi potrebbero penalizzare la query quando vengono utilizzati altri oggetti per il filtro ma non restituire i dati ( SELECT * FROM table1 WHERE id IN (SELECT someID FROM table2 WHERE someColumn='DesiredValue')
forse).
Un'altra considerazione per lo spazio in eccesso utilizzato, in particolare se i dati sono di grandi dimensioni, è che avrà un impatto sulla strategia di backup: costi di archiviazione e trasferimento per tali backup, tempi di ripristino potenziali e così via.
dovremmo essere preparati per eventuali differenze tra i due [on-prem e AzureSQL]
In generale, penso che le considerazioni qui saranno le stesse in ogni caso, sebbene l'eventuale costo in eccesso di memoria / I / O imposto dagli indici di grandi dimensioni potrebbe essere più direttamente visibile in Azure dove è possibile modificare il livello di servizio e quindi il costo dell'infrastruttura più facilmente anziché avere un set relativamente fisso di risorse hardware. Se si utilizzano livelli standard / premium invece di prezzi basati su vcore, il costo di I / O standard sarà influenzato maggiormente dal momento che il premio include significativamente più I / O per DTU. Se si usano backup o ridondanze multi-regione o altre funzionalità non locali in Azure, potrebbe esserci un costo di larghezza di banda associato allo spazio aggiuntivo occupato da indici non necessari.
SELECT
senza specificare haORDER BY
iniziato a restituire le stesse righe di prima ma con un ordine arbitrario diverso.