Являются ли нефиксируемые искажения пространственного индекса нормальными?

23

У меня есть пространственный индекс, для которого DBCC CHECKDBсообщает о коррупции:

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

Пространственный индекс, XML-индекс или индексированное представление 'sys.extended_index_xxx_384000' (идентификатор объекта xxx) не содержит все строки, которые создает определение представления. Это не обязательно представляет проблему целостности данных в этой базе данных.

Пространственный индекс, XML-индекс или индексированное представление 'sys.extended_index_xxx_384000' (идентификатор объекта xxx) содержит строки, которые не были созданы определением представления. Это не обязательно представляет проблему целостности данных в этой базе данных.

CHECKDB обнаружил 0 ошибок размещения и 2 ошибки согласованности в таблице 'sys.extended_index_xxx_384000' (идентификатор объекта xxx).

Уровень ремонта есть repair_rebuild.

Удаление и повторное создание индекса не удаляет эти отчеты о повреждениях. Без EXTENDED_LOGICAL_CHECKSно с DATA_PURITYошибкой не сообщается.

Кроме того, CHECKTABLEзанимает 45 минут для этой таблицы, хотя ее CI составляет 30 МБ и около 30 тыс. Строк. Все данные в этой таблице являются точечными geographyданными.

Ожидается ли такое поведение при любых обстоятельствах? Он говорит: «Это не обязательно представляет проблему целостности». Что я должен сделать? CHECKDBтерпит неудачу, которая является проблемой.

Этот скрипт воспроизводит проблему:

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

Это версия 12.0.4427.24 (SQL Server 2014 с пакетом обновления 1 (SP1) CU3).

Я заскриптовал таблицу со схемой и данными, свежую БД, выполнил. Та же ошибка CHECKDB также имеет это невероятное время выполнения 45 минут. Я захватил план запроса CHECKDB, используя SQL Profiler. Он имеет ошибочное объединение циклов, что, очевидно, вызывает чрезмерное время выполнения. План имеет квадратичное время выполнения по количеству строк таблицы! Дважды вложенный цикл сканирования включается.

План выполнения DBCC

Очистка всех непространственных индексов ничего не меняет.

boot4life
источник

Ответы:

25

Я не смог сразу воспроизвести это в 2014 году - 12.0.4213.0, но вижу это на SQL Server 2016 (CTP3.0) - 13.0.700.242.

В сборке 2014 года (без ошибок DBCC) план выглядит следующим образом.

введите описание изображения здесь

И на сборке 2016 года ( с сообщениями об ошибках DBCC) вот так.

введите описание изображения здесь

Второй план имеет единственную строку, выходящую из слияния анти-полусоединения, первый план - нулевые строки.

Предикаты соединения отличаются по отношению к тому, что сопоставляется со pk0столбцом в пространственном индексе.

введите описание изображения здесь

Первый правильно сопоставляет его с таблицей Primary Key, второй сопоставляет его со Idстолбцом, возвращенным из TVF.

Согласно книге по внутренним компонентам SQL Server 2012, это двоичное значение (5) для числа Гильберта ячейки, поэтому этот предикат, безусловно, является неправильным (если для единственной строки в базовой таблице задано значение 1052031049 вместо 20171, я не больше видеть ошибки DBCC, так как это соответствует этому значению 0xa03eb4b849).


В 2014 году - 12.0.4213.0 после повторного создания таблицы следующим образом я мог воспроизвести проблему.

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

(Обратите внимание на изменение с IDна Id)

Мой экземпляр 2014 года установлен с учетом регистра. Похоже, это могло предотвратить путаницу в колонке раньше.

Таким образом , я предполагаю , что потенциальный обходной путь может быть переименовать столбец в Citiesкачестве CityId, например.

Connect Item (отчет об ошибке Microsoft)

Мартин Смит
источник
4
Это фантастическая ошибка :) Может также объяснить сумасшедшие соединения цикла, потому что они могут быть просто хорошим выбором для этого условия соединения с более высокой кардинальностью.
boot4life
7
@ boot4life IdПутаница также вызывает сканирование. Отличный улов, Мартин. Это только влияет на AUTO_GRIDопцию. Я могу воспроизвести ошибку на 2014 SP1 CU4 с учетом регистра без учета регистра. SQL Server неправильно строит запрос расширенных проверок.
Пол Уайт говорит GoFundMonica