TL; DR: ho una corruzione non riparabile in una vista indicizzata. Ecco i dettagli:
In esecuzione
DBCC CHECKDB([DbName]) WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS
su uno dei miei database produce il seguente errore:
Messaggio 8907, livello 16, stato 1, riga 1 L'indice spaziale, l'indice XML o la vista indicizzata 'ViewName' (ID oggetto 784109934) contiene righe che non sono state prodotte dalla definizione della vista. Ciò non rappresenta necessariamente un problema di integrità con i dati in questo database. (...)
CHECKDB ha trovato 0 errori di allocazione e 1 errori di coerenza nella tabella 'ViewName'.
repair_rebuild è il livello di riparazione minimo (...).
Comprendo che questo messaggio indica che i dati materializzati della vista indicizzata 'ViewName' non sono identici a ciò che produce la query sottostante. Tuttavia, la verifica manuale dei dati non presenta alcuna discrepanza:
SELECT * FROM ViewName WITH (NOEXPAND)
EXCEPT
SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...
SELECT ...
from T1 WITH (FORCESCAN)
join T2 on ...
EXCEPT
SELECT * FROM ViewName WITH (NOEXPAND)
NOEXPAND
è stato usato per forzare l'uso del (solo) indice su ViewName
. FORCESCAN
è stato utilizzato per impedire la corrispondenza della vista indicizzata. Il piano di esecuzione conferma che entrambe le misure funzionano.
Qui non vengono restituite righe, il che significa che le due tabelle sono identiche. (Esistono solo colonne di numeri interi e guid, le regole di confronto non entrano in gioco).
L'errore non può essere corretto ricreando l'indice sulla vista o eseguendolo DBCC CHECKDB REPAIR_ALLOW_DATA_LOSS
. Anche ripetere le correzioni non ha aiutato. Perché DBCC CHECKDB
segnala questo errore? Come sbarazzarsene?
(Anche se la ricostruzione avesse risolto il problema, la mia domanda sarebbe ancora valida: perché viene segnalato un errore anche se le mie query di controllo dei dati vengono eseguite correttamente?)
Aggiornamento: il bug è stato corretto in alcune versioni. Non riesco più a riprodurre in SQL Server 2014 SP2 CU 5. Il 2014 SP2 KB contiene una correzione senza articolo KB: Creating non-clustered index causes DBCC CheckDB With Extended_Logical_Checks to raise corruption error
. I due bug di connessione su questo sono stati chiusi:
- https://connect.microsoft.com/SQLServer/feedback/details/847233/creating-non-clustered-index-causes-dbcc-checkdb-with-extended-logical-checks-to-raise-corruption-error
- https://connect.microsoft.com/SQLServer/feedback/details/795478/unfixable-dbcc-checkdb-error-that-is-also-a-false-positive-and-otherwise-strange
If the indexed view does not contain an aggregate over values of type float or real and you receive errors 8907 or 8708, drop the index on the view and re-create it. Do not use ALTER INDEX REBUILD to try to remove the differences between the stored and the computed view, because ALTER INDEX REBUILD does not recalculate the view before rebuilding the index. Then run DBCC CHECKTABLE on the View to verify no differences remain.
[1]
notazione non funziona nel mark-down dei commenti.