Индекс покрытия, включая Rowversion? Хорошо или плохо - PullRequest
0 голосов
/ 28 февраля 2020

Я работаю над синхронизацией клиентов с данными для возможной согласованности. Сервер опубликует sh список идентификаторов базы данных и rowversion / timestamp. Затем клиент запросит данные с неверным номером версии. Основной причиной противоречивых данных являются проблемы с сетью между узлами-брокерами, разделение мозга и т. Д. c.

Когда я читаю данные из моих таблиц, я запрашиваю данные на основе предиката, который не является первичным ключом. Я перебираю доступные регионы для чтения данных по регионам. Это мой выбор:

SELECT DatabaseId, VersionTimestamp, OperationId
FROM TableX 
WHERE RegionId = 1

Так как это приводит к сканированию индекса для запроса, мне интересно, есть ли некластеризованный индекс в моем столбце RegionId, и включить выбранные столбцы в этом индексе:

CREATE NONCLUSTERED INDEX [ID_TableX_RegionId_Sync]
ON [dbo].[TableX] ([RegionId])
INCLUDE ([DatabaseId],[VersionTimestamp],[OperationId])

VersionTimestamp - это столбец rowversion / timestamp, и, конечно, он будет меняться при каждом обновлении строки, поэтому мне интересно, не является ли это плохим выбором дизайна для включить этот столбец в индекс, поскольку его нужно будет обновлять при каждой вставке / обновлении / удалении?

Так как это приведет к сканированию индекса n , а не n Индекс ищет, может быть, лучше прочитать все данные один раз, а затем сгруппировать по regionId и заполнить пустые списки строк, где regionId не имеет данных.

Реальный сценарий немного более сложный, поскольку существуют таблицы отношений, которые также должны быть запрошены. Я еще не рассматривал возможность включения отношений один-ко-многим в мои запросы версий.

Это прежде всего для лучшего понимания влияния покрытия индексов и выяснения, как лучше их использовать. Поскольку я собираюсь прочитать все данные из таблицы в любом случае, вероятно, дешевле загрузить их все сразу. Однако, читая их, как в приведенном выше запросе, он делает мой код намного чище только для этого простого примера отсутствия отношений.

Редактировать: Альтернатива 2 Еще одна опция, которая пришла в голову, это создать индекс покрытия для RegionId и включить мой первичный ключ (DatabaseId).

SELECT DatabaseId
FROM TableX WHERE RegionId=1

И затем новый запрос, в котором я выбираю необходимые столбцы, ГДЕ DatabaseId IN (list, of, databaseId)

Для текущего сценария в макс. Тысячах строк стол, а не в миллионах. Сетевой трафик c для двух (x n ) запросов, скорее всего, может перевесить преимущества использования индексов и привести к преждевременной оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...