Implicazioni dell'utilizzo di un indice non cluster univoco con colonne di copertura anziché una chiave primaria


12

Abbiamo una grande tabella [MyTable]che attualmente ha sia a Primary Key, sia a Unique Non Clustered Indexsulla stessa colonna ( [KeyColumn]). L'indice U NC ha anche colonne di copertura aggiuntive.

Avere PK e Unique NC Index sulle stesse colonne sembra ridondante, quindi stavo considerando di eliminare la chiave primaria e invece di utilizzare l'indice univoco non cluster per scopi di integrità referenziale.

Si noti che la tabella è interamente raggruppata da un'altra colonna.

cioè Quindi abbiamo:

ALTER TABLE [MyTable]
    ADD CONSTRAINT [PK_MyTable] 
    PRIMARY KEY NONCLUSTERED ([KeyColumn])
GO

E

CREATE UNIQUE NONCLUSTERED INDEX [IX_MyTable_SomeIndex] 
    ON [MyTable] ([KeyColumn]) 
    INCLUDE ([Column1], [Column2])
GO

Per quanto ne so, non è possibile aggiungere colonne di copertura a una chiave primaria, quindi intendo fare:

  • Eliminare i vincoli di chiave esterna su cui fare affidamento MyTable.KeyColumn
  • Eliminare la chiave primaria su MyTable.KeyColumntutto
  • Aggiungi nuovamente le chiavi esterne alla tabella (ovvero il RI verrà applicato tramite MyTable.KeyColumn)

L'unica conseguenza che posso pensare di fare questo è che non otterremo il simbolo della chiave visiva sui nostri diagrammi ERD e che la densità dell'indice (foglia) sarà inferiore a causa delle colonne incluse.

Ho letto /programming/487314/primary-key-or-unique-index e sono contento degli aspetti di integrità e prestazioni di questo.

La mia domanda è: questo approccio è imperfetto?

Modifica Cosa sto cercando di realizzare : ottimizzazione delle prestazioni e pulizie di primavera . Rimuovendo il PK o un indice, ci saranno meno pagine necessarie per i miei indici = scritture più veloci, oltre a vantaggi di manutenzione / operativi, ovvero un indice in meno per mantenere la deframmentazione, ecc.

Per farci un'idea, non avevo mai avuto una tabella a cui si fa riferimento, senza un PK. Tuttavia, il fatto che un indice NC con colonne di copertura sia stato aggiunto alla tabella significa che devo adattare il mio pensiero.


Potresti commentare ciò che stai cercando di realizzare? Dovresti anche assicurarti di finire con un indice cluster alla fine.

@ jn29098 - Aggiornato. Confermato che abbiamo un indice cluster, su colonne che non sono né il PK né le colonne di copertura, quindi questo non sembra rilevante per questa decisione.
StuartLC,

1
Sei sicuro di non avere nessuno strumento / ORM / strumento di modellazione di generazione di dati che fallirà quando vedrà scomparire il PK?
Remus Rusanu,

L'unico svantaggio che vedo è che una volta che PK è sparito ... allora hai un solo indice sulla colonna chiave e le query che usano l'indice PK dicono che la scansione dell'indice sulla colonna chiave o l'ordine per colonne chiave e non sono coperte dall'indice Uniuqe potrebbero avere un clock in qualche modo extra di IO dato che le pagine fogliare uniche sono molto più di quelle del PK. Altrimenti sembra a posto, ma alcuni puristi diranno che dovresti avere il PK :)
Gulli Meel,

1
Ti suggerirei di verificare l'utilità di quell'indice utilizzando le statistiche di utilizzo dell'indice DMV e di vedere se viene utilizzato da alcune delle tue query. Verificalo anche con l'indice chiave univoco e quindi deicca cosa accadrà alla query usando quello indice ..
Gulli Meel,

Risposte:


3

Ottimizzazione delle prestazioni. Rimuovendo il PK o un indice, ci saranno meno pagine necessarie per i miei indici = scritture più veloci, oltre a vantaggi di manutenzione / operativi, ovvero un indice in meno per mantenere la deframmentazione, ecc.

Devi essere in grado di dimostrare che ciò che viene proposto sarà effettivamente di aiuto (costo vs. beneficio). Per quale motivo viene preso in considerazione questo cambiamento? Esistono effettivamente problemi di prestazioni con questa tabella o ha semplicemente "un aspetto sbagliato"?

Ecco alcune altre domande che ti aiuteranno a prendere la decisione migliore per il tuo ambiente:

  • Quanto tempo verrebbe risparmiato nella finestra di manutenzione? Nella finestra di backup?

  • Quanto spazio di archiviazione risparmierebbe (file di dati, file di registro, backup, ecc.)?

  • Le INSERTprestazioni su questo tavolo sono davvero un collo di bottiglia in questo momento? Quanto migliorerebbe? Rimuovere un indice è la migliore strategia per risolvere quel problema?

  • Ciò causerà problemi con strumenti e framework di database (in particolare ORM) che prevedono che ogni tabella abbia una chiave primaria e non solo un indice univoco? La replica transazionale richiede una chiave primaria nelle tabelle pubblicate.

  • È importante uno schema di database auto-documentante?

  • Nonostante il suo uso limitato, la ristrettezza dell'indice della chiave primaria consente ancora all'ottimizzatore di produrre piani più efficienti per determinate query? (Utilizzare sys.dm_db_index_usage_statsper scoprirlo.)

Personalmente, da quello che ci hai detto, lo lascerei da solo fino a quando non sarà dimostrato che sia (a) l'indice aggiuntivo è un problema, sia (b) rimuoverlo è la soluzione.


Grazie - risulta che le statistiche dell'indice hanno mostrato che il PK era ancora ampiamente utilizzato per le scansioni. Sembra che stia diventando troppo zelante: i vantaggi di leggibilità / convenzione del mantenimento del PK dovrebbero superare le implicazioni di archiviazione a lungo termine. Il punto sulla replica transazionale lo conferma però: dovremo replicare questo database a breve.
StuartLC,

2

L'unico tipo di query su quella tabella che avrà prestazioni peggiori (e solo leggermente peggiori) saranno quelli che richiedono un intervallo di valori KeyColumn - poiché quelle query al momento sarebbero meglio servite da una ricerca dell'indice sul tuo PK.

Vale la pena ricordare che il costo del controllo dell'integrità referenziale per le tabelle che fanno riferimento a questa tabella sarà più elevato (di nuovo solo leggermente superiore).

Finché ti prendi cura dell'aspetto nullable, allora dovresti andare bene con l'unico indice.

Se fosse il mio DB, probabilmente sceglierei il singolo indice univoco, a parità di altre condizioni.


Grazie - hai dei link di riferimento? leggermente peggiorato, ti riferisci esclusivamente alla densità dell'indice più bassa nell'indice di copertura o c'è qualcos'altro che potrebbe causare questo?
StuartLC,

Purtroppo è solo per molta esperienza, e chattare con persone molto più intelligenti di me nel corso degli anni! E sì, è proprio questo: ci saranno meno righe per pagina, quindi più I / O. Tuttavia, vale la pena notare che le colonne INCLUDE sono presenti solo a livello foglia. Quindi non è tutto male. Sono sicuro che lo sai sulla base dei dettagli nella tua domanda, ma suppongo che altri lettori potrebbero non esserlo.
Matt Whitfield,

-2

Per quanto ne so, non è possibile aggiungere colonne di copertura a una chiave primaria

Se si dispone di un indice cluster su KeyColumn, quindi poiché si tratta di un indice cluster, tutte le altre colonne vengono implicitamente "coperte". Quindi non ottieni nulla aggiungendo un altro indice su KeyColumn. In effetti rallenterai gli inserti e utilizzerai più spazio.

Questo perché un indice cluster non è un indice in quanto tale, ma solo un'istruzione per memorizzare le righe della tabella nell'ordine dell'indice. E una volta che hai trovato una riga con la chiave primaria, allora hai tutte le altre colonne proprio lì.


2
Dal primo paragrafo:The table is clustered by another column entirely.
JNK,

5
Penso che potrebbe esserci qualche chiave primaria / confusione dell'indice cluster in corso qui. Nonostante i migliori sforzi dello studio di gestione per convincerti così, non sono la stessa cosa.
Matt Whitfield,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.