Мы переносим существующее настольное приложение компании в облако. Я много работал с базами данных и оптимизировал их для соответствующих индексов, чтобы поддерживать скорость реагирования по мере необходимости.
Я пытался оптимизировать пару таблиц и не мог заставить индексы вести себя во всех вызовах, которые я тоже хотел, поэтому попробовал неуникальный ключ кластера во временной таблице, чтобы увидеть, даст ли он мне лучшие числа, поскольку они имеют локальность на диске, поэтому он должен быть в состоянии найти их с помощью последовательного чтения, а не повторного случайного чтения ».
У меня есть 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, чтобы вы могли гарантировать локальность диска. Я просто недостаточно знаком с производительностью вставки, чтобы увидеть, не возникнут ли неожиданные проблемы с перестроением дерева.
В живом окружении вставки, вероятно, были бы более «случайными», чем мои тесты. Я просто тестировал вставку кучу записей для 1 CustomerID. Другая таблица, которую я предполагаю, заключается в том, что она должна вставить их в конец таблицы, а затем вставить их во второй индекс. Если оптимизатор понимает, что он может выполнить вставку одного диапазона для идентификатора клиента или оставляет место для дополнительных записей, это не совсем странно, но я не знаю, так ли ведет себя сервер. В реальном приложении было бы много вызовов ко многим идентификаторам клиентов, поскольку для этого потребовалось бы более серьезное тестовое приложение, чем я сделал.
Если ваши важные запросы выполняются по CustomerID, было бы лучше сделать кластерный индекс CustomerID (и, возможно, SettingTypeID) и изменить свой индекс первичного ключа на некластеризованный. Если у вас нет других таблиц, ссылающихся на эту таблицу по SettingID, вам может быть лучше с составным кластеризованным первичным ключом CustomerID и другими столбцами. Индексирование во многом зависит от ваших запросов.





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