Eu tenho um índice espacial para o qual DBCC CHECKDB
relata corrupções:
DBCC CHECKDB(MyDB)
WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS, TABLERESULTS
O índice espacial, índice XML ou exibição indexada 'sys.extended_index_xxx_384000' (objeto ID xxx) não contém todas as linhas que a definição de exibição produz. Isso não representa necessariamente um problema de integridade com os dados desse banco de dados.
O índice espacial, índice XML ou exibição indexada 'sys.extended_index_xxx_384000' (objeto ID xxx) contém linhas que não foram produzidas pela definição de exibição. Isso não representa necessariamente um problema de integridade com os dados desse banco de dados.
CHECKDB encontrou 0 erros de alocação e 2 erros de consistência na tabela 'sys.extended_index_xxx_384000' (objeto ID xxx).
O nível de reparo é repair_rebuild
.
Eliminar e recriar o índice não remove esses relatórios de corrupção. Sem EXTENDED_LOGICAL_CHECKS
, mas com DATA_PURITY
o erro não é relatado.
Além disso, CHECKTABLE
leva 45 minutos para esta tabela, embora seu CI tenha 30 MB de tamanho e haja cerca de 30 mil linhas. Todos os dados nessa tabela são geography
dados pontuais.
Esse comportamento é esperado em alguma circunstância? Ele diz "Isso não representa necessariamente um problema de integridade". O que eu deveria fazer? CHECKDB
está falhando, o que é um problema.
Este script reproduz o problema:
CREATE TABLE dbo.Cities(
ID int NOT NULL,
Position geography NULL,
CONSTRAINT PK_Cities PRIMARY KEY CLUSTERED
(
ID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
INSERT dbo.Cities (ID, Position) VALUES (20171, 0xE6100000010C4E2B85402E424A40A07312A518C72A40)
GO
CREATE SPATIAL INDEX IX_Cities_Position ON dbo.Cities
(
Position
)USING GEOGRAPHY_AUTO_GRID
WITH (
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Esta é a versão 12.0.4427.24 (SQL Server 2014 SP1 CU3).
Eu criei o script da tabela com esquema e dados, banco de dados fresco, execute. Mesmo erro. CHECKDB também tem esse tempo de execução incrível de 45min. Eu capturei o plano de consulta CHECKDB usando o SQL Profiler. Ele tem uma junção de loop equivocada, aparentemente causando tempo de execução excessivo. O plano tem tempo de execução quadrático no número de linhas da tabela! Junções de loop de varredura duplamente aninhadas.
Limpar todos os índices não espaciais não altera nada.
Não consegui reproduzir isso imediatamente em 2014 - 12.0.4213.0, mas vejo no SQL Server 2016 (CTP3.0) - 13.0.700.242.
Na compilação de 2014 (sem erros de DBCC), o plano tem a seguinte aparência.
E na compilação de 2016 ( com erros de DBCC relatados) assim.
O segundo plano tem uma única linha saindo do merge anti semi join, o primeiro plano zero linhas.
Os predicados de junção são diferentes em relação ao que corresponde à
pk0
coluna no índice espacial.A primeira mapeia corretamente para a chave primária da tabela, a segunda mapeia para a
Id
coluna retornada do TVF.De acordo com o livro interno do SQL Server 2012, este é um valor binário (5) para o número de Hilbert da célula, portanto, esse predicado certamente está incorreto (se o ID da única linha na tabela base estiver definido como 1052031049 em vez de 20171, não não verá mais nenhum erro DBCC, pois isso corresponde a esse valor de
0xa03eb4b849
).Em 2014 - 12.0.4213.0, após recriar a tabela da seguinte maneira, consegui reproduzir o problema.
(Observe a mudança de
ID
paraId
)Minha instância de 2014 é instalada com agrupamento sensível a maiúsculas e minúsculas. Portanto, parece que isso pode ter evitado a confusão da coluna antes.
Portanto, acho que uma possível solução alternativa pode ser renomear a coluna
Cities
como,CityId
por exemplo.Conectar item (relatório de bug da Microsoft)