Czy niemożliwe do naprawienia uszkodzenia indeksów przestrzennych są normalne?

23

Mam indeks przestrzenny, dla któregoDBCC CHECKDB zgłaszane są uszkodzenia:

DBCC CHECKDB(MyDB) 
WITH EXTENDED_LOGICAL_CHECKS, DATA_PURITY, NO_INFOMSGS, ALL_ERRORMSGS, TABLERESULTS

Indeks przestrzenny, indeks XML lub widok indeksowany „sys.extended_index_xxx_384000” (identyfikator obiektu xxx) nie zawiera wszystkich wierszy tworzonych przez definicję widoku. Nie musi to oznaczać problemu z integralnością danych w tej bazie danych.

Indeks przestrzenny, indeks XML lub widok indeksowany „sys.extended_index_xxx_384000” (identyfikator obiektu xxx) zawiera wiersze, które nie zostały utworzone przez definicję widoku. Nie musi to oznaczać problemu z integralnością danych w tej bazie danych.

CHECKDB znalazł 0 błędów alokacji i 2 błędy spójności w tabeli „sys.extended_index_xxx_384000” (identyfikator obiektu xxx).

Poziom naprawy wynosi repair_rebuild .

Usunięcie i ponowne utworzenie indeksu nie usuwa tych raportów o uszkodzeniach. Bez EXTENDED_LOGICAL_CHECKSale zDATA_PURITY błędem nie jest zgłaszany.

Również CHECKTABLEta tabela zajmuje 45 minut, chociaż jej CI ma rozmiar 30 MB i jest około 30 000 wierszy. Wszystkie dane w tej tabeli są punktowegeography danymi .

Czy w takich okolicznościach można się spodziewać takiego zachowania? Mówi: „To niekoniecznie oznacza problem z uczciwością”. Co powinienem zrobić? CHECKDBzawodzi, co stanowi problem.

Ten skrypt odtwarza problem:

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

To jest wersja 12.0.4427.24 (SQL Server 2014 SP1 CU3).

Skryptowałem tabelę ze schematem i danymi, świeżą bazą danych, uruchom. Ten sam błąd. CHECKDB ma również ten niesamowity czas działania wynoszący 45 minut. Przechwyciłem plan zapytań CHECKDB przy użyciu SQL Profiler. Ma błędnie sprzężoną pętlę, co najwyraźniej powoduje nadmierne działanie. Plan ma kwadratowy czas działania w liczbie wierszy tabeli! Łączy się podwójnie zagnieżdżona pętla skanująca.

Plan wykonania DBCC

Wyczyszczenie wszystkich indeksów nieprzestrzennych niczego nie zmienia.

boot4life
źródło

Odpowiedzi:

25

Nie mogłem od razu odtworzyć tego w 2014 - 12.0.4213.0, ale widzę to na SQL Server 2016 (CTP3.0) - 13.0.700.242.

W wersji 2014 (bez błędów DBCC) plan wygląda następująco.

wprowadź opis zdjęcia tutaj

I w wersji 2016 ( z zgłoszonymi błędami DBCC) w ten sposób.

wprowadź opis zdjęcia tutaj

Drugi plan ma pojedynczy rząd wychodzący ze scalania przeciw pół złączeniu, pierwszy plan zeruje rzędy.

Predykaty łączenia są różne pod względem dopasowania do pk0kolumny w indeksie przestrzennym.

wprowadź opis zdjęcia tutaj

Pierwszy poprawnie mapuje go na klucz podstawowy tabeli, drugi mapuje Idkolumnę zwróconą z TVF.

Zgodnie z książką wewnętrzną SQL Server 2012 jest to wartość binarna (5) dla liczby Hilberta komórki, więc ten predykat z pewnością jest niepoprawny (jeśli identyfikator pojedynczego wiersza w tabeli podstawowej jest ustawiony na 1052031049 zamiast 20171, nie dłużej widzą jakiekolwiek błędy DBCC, ponieważ tak się dzieje, że odpowiada to tej wartości 0xa03eb4b849).


W dniu 2014 - 12.0.4213.0 po ponownym utworzeniu tabeli w następujący sposób mogłem odtworzyć problem.

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)
)

(Uwaga zmiana z IDna Id)

Moja instancja 2014 jest instalowana z sortowaniem z rozróżnianiem wielkości liter. Wygląda więc na to, że mogło to wcześniej zapobiec pomyłkom w kolumnach.

Więc myślę, że potencjalny Rozwiązaniem może być zmiana nazwy kolumny w Citiesjak CityIdna przykład.

Połącz element (raport o błędach Microsoft)

Martin Smith
źródło
4
To fantastyczny błąd :) Może również wyjaśniać połączenia szalonej pętli, ponieważ mogą one być po prostu dobrym wyborem dla tego warunku połączenia o prawdopodobnie większej liczności.
boot4life
7
@ boot4life IdZamieszanie powoduje również, że powinien być to skan. Świetny chwyt, Martin. Wydaje się, że wpływa to tylko na AUTO_GRIDopcję. Mogę odtworzyć błąd na 2014 SP1 CU4 z sortowaniem bez rozróżniania wielkości liter. Program SQL Server niepoprawnie tworzy zapytanie kontroli rozszerzonej.
Paul White mówi GoFundMonica