As corrupções de índice espacial não corrigíveis são consideradas normais?

23

Eu tenho um índice espacial para o qual DBCC CHECKDBrelata 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' (ID do objeto xxx) não contém todas as linhas que a definição da exibição produz. Isso não representa necessariamente um problema de integridade com os dados desse banco de dados.

O índice espacial, o índice XML ou a exibição indexada 'sys.extended_index_xxx_384000' (ID do objeto xxx) contém linhas que não foram produzidas pela definição da exibição. Isso não representa necessariamente um problema de integridade com os dados desse banco de dados.

O CHECKDB encontrou 0 erros de alocação e 2 erros de consistência na tabela 'sys.extended_index_xxx_384000' (ID do objeto xxx).

O nível de reparo é repair_rebuild.

Descartar e recriar o índice não remove esses relatórios de corrupção. Sem EXTENDED_LOGICAL_CHECKSmas com DATA_PURITYo erro não é relatado.

Além disso, CHECKTABLEleva 45 minutos para esta tabela, embora seu IC tenha 30 MB de tamanho e existam cerca de 30k linhas. Todos os dados nessa tabela são geographydados pontuais .

Esse comportamento é esperado sob alguma circunstância? Ele diz "Isso não representa necessariamente um problema de integridade". O que eu deveria fazer? CHECKDBestá 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 escrevi a tabela com esquema e dados, DB novo, execute. Mesmo erro. O CHECKDB também possui esse incrível tempo de execução de 45 minutos. 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 possui tempo de execução quadrático no número de linhas da tabela! Junções de loop de verificação duplamente aninhadas.

Plano de execução do DBCC

A limpeza de todos os índices não espaciais não altera nada.

boot4life
fonte

Respostas:

25

Não foi possível reproduzir isso imediatamente em 2014 - 12.0.4213.0, mas o vejo no SQL Server 2016 (CTP3.0) - 13.0.700.242.

Na versão de 2014 (sem erros de DBCC), o plano é o seguinte.

insira a descrição da imagem aqui

E na compilação de 2016 ( com erros de DBCC relatados) assim.

insira a descrição da imagem aqui

O segundo plano possui uma única linha saindo da mesclagem anti-junção semi, as primeiras zero linhas do plano.

Os predicados de junção são diferentes em relação ao que corresponde à pk0coluna no índice espacial.

insira a descrição da imagem aqui

O primeiro mapeia corretamente para a tabela Chave Primária. O segundo mapeia para a Idcoluna retornada do TVF.

De acordo com o livro interno do SQL Server 2012, esse é um valor binário (5) para o número 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 ver mais erros de DBCC, pois isso corresponde a esse valor de 0xa03eb4b849).


Em 2014 - 12.0.4213.0 após recriar a tabela da seguinte maneira, eu pude reproduzir 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)
)

(Observe a alteração de IDpara Id)

Minha instância de 2014 é instalada com agrupamento com distinção entre 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 seria renomear a coluna Citiescomo CityIdpor exemplo.

Item de conexão (relatório de bug da Microsoft)

Martin Smith
fonte
4
Este é um bug fantástico :) Também pode explicar as junções malucas do loop, porque elas podem ser simplesmente uma boa opção para essa condição de junção com cardinalidade possivelmente mais alta.
Boot4life
7
@ boot4life A Idconfusão também faz com que o que deveria ser uma busca seja uma verificação. Ótima captura, Martin. Parece apenas afetar a AUTO_GRIDopção. Eu posso reproduzir o bug no 2014 SP1 CU4 com um agrupamento sem distinção entre maiúsculas e minúsculas. O SQL Server cria a consulta de cheques estendidos incorretamente.
Paul White diz GoFundMonica