SQL Server - оптимизация неуникального кластерного индекса

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

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

У меня есть 2 таблицы проблем, которые определенно будут составлять большую часть трафика, но проблема та же. Мы ожидаем от миллионов до десятков миллионов записей в нашей таблице пользовательских настроек. Я подтвердил, что наше устаревшее программное обеспечение будет синхронизировать с базой данных ~ 1300-1500 параметров конфигурации для каждого пользователя. Ожидайте, что размер таблицы составит не менее ~ 40-50 миллионов строк.

Мой первоначальный дизайн стола был таким

    CREATE TABLE dbo.Settings
    (
       SettingID BIGINT PRIMARY KEY NOT NULL IDENTITY(1,1),
       CustomerID INT NOT NULL,
       SettingTypeID INT NOT NULL
       .... other rows
    )

CREATE NONCLUSTERED INDEX [INDEX_NAME] ON dbo.Settings(CustomerID);

Я думаю, что лучшая оптимизация - это

CREATE TABLE dbo.Settings
(
   CustomerID INT NOT NULL,
   SettingTypeID INT NOT NULL,
   .... other rows
)

CREATE CLUSTERED INDEX [INDEX_NAME] ON dbo.TRSettings(CustomerID);

Все запросы для продукта будут иметь форму, возможно, с каким-то дополнительным условием where, например, с конкретными настройками, которые я хочу для данной страницы.

SELECT * FROM dbo.Settings WHERE CustomerID=@CustomerID ...

Из профилирования выборка кажется в 5-50 раз быстрее, в среднем примерно в 25-30 раз быстрее. Поскольку он может выполнять сканирование диапазона, а не повторные поиски из некластеризованного индекса.

По какой-то причине вставки читают то же самое на 50% быстрее в некоторых из моих тестов (я предполагаю, что он должен перестроить некластеризованный индекс и записать в фактическую таблицу).

Довел его до нашего лидера по продукту, и, похоже, сейчас консенсус таков: `` мы добавим в него больше оборудования, если необходимо '', поскольку нам пришлось бы потратить около полдня, чтобы переписать некоторый код, чтобы он работал (довольно положительно, новая таблица не сработает с entity framework или вы можете получить доступ к скрытому столбцу uniquifier?), но насколько мне известно, есть ли какие-то проблемы, о которых я не знаю? Похоже, что для записей клиентов, где вы часто будете индексировать несколько номеров элементов (например, пользовательские настройки), лучше всего иметь такой индекс, который приближается к кластеризации NoSQL, чтобы вы могли гарантировать локальность диска. Я просто недостаточно знаком с производительностью вставки, чтобы увидеть, не возникнут ли неожиданные проблемы с перестроением дерева.

«в некоторых моих тестах вставки читают то же самое на 50% быстрее». Это не имеет никакого смысла.

Gordon Linoff 27.04.2018 17:48

В живом окружении вставки, вероятно, были бы более «случайными», чем мои тесты. Я просто тестировал вставку кучу записей для 1 CustomerID. Другая таблица, которую я предполагаю, заключается в том, что она должна вставить их в конец таблицы, а затем вставить их во второй индекс. Если оптимизатор понимает, что он может выполнить вставку одного диапазона для идентификатора клиента или оставляет место для дополнительных записей, это не совсем странно, но я не знаю, так ли ведет себя сервер. В реальном приложении было бы много вызовов ко многим идентификаторам клиентов, поскольку для этого потребовалось бы более серьезное тестовое приложение, чем я сделал.

Chase R Lewis 27.04.2018 17:58

Если ваши важные запросы выполняются по CustomerID, было бы лучше сделать кластерный индекс CustomerID (и, возможно, SettingTypeID) и изменить свой индекс первичного ключа на некластеризованный. Если у вас нет других таблиц, ссылающихся на эту таблицу по SettingID, вам может быть лучше с составным кластеризованным первичным ключом CustomerID и другими столбцами. Индексирование во многом зависит от ваших запросов.

Dan Guzman 28.04.2018 02:52
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
701
0

Другие вопросы по теме