У нас есть большая база данных (> 1 ТБ), которую мы намерены «сжать». База данных вращается вокруг одного основного объекта, назовем его «Визит». Для обсуждения, скажем, это база данных для медицинской практики.
Всего существует 30 «типов» посещений, таких как процедура, ежегодное обследование, последующее наблюдение, иммунизация и т. Д., Каждый из которых является вспомогательной таблицей «Визит», например, «визит_иммуно».
База данных накопила около 12 лет данных с 2000 года. Кто-то предложил сохранить данные за 3 года в «живой» версии, а остальные - в базе данных «old_data». Дата хранится ТОЛЬКО в таблице посещений, поскольку она нормализована. Таблица посещений также содержит ROWVERSION
столбец и столбец BIGINT
псевдоидентификации (кластеризованный). Допустим, для всех целей и задач ключ кластеризации заполняется SEQUENCE (SQL Server 2012 Enterprise) - назовем его cid
.
Он visit.date
не всегда находится в том же порядке, что и ключ кластеризации, например, когда врач часто посещает и возвращается со своим «портфелем» данных, он объединяется в основную таблицу. Есть также некоторые обновления для «визита» таблицы , которая заставит ROWVERSION
столбец быть синхронизированы с обеими cid
и date
столбцами - попросту говоря, ни ROWVERSION
ни cid
был сделать соответствующие ключи разделов по этой причине.
Бизнес-правило для удаления данных из «живого» заключается в том, что visit.date
должно быть больше 36 месяцев иvisit_payment
должна существовать дочерняя запись. Кроме того, база данных «old_data» не содержит никаких базовых таблиц, кроме visit%
.
Итак, мы заканчиваем с:
Live DB (ежедневное использование) - все таблицы Old-Data DB - более старые данные для visit%
таблиц
В предложении предлагается объединенная БД, представляющая собой оболочку, содержащую синонимы для ВСЕХ базовых таблиц в Live DB
(кроме visit%
) и представлениях, которые СОЕДИНЯЮТСЯ ВСЕМ по всем visit%
таблицам в двух базах данных.
Предполагая , что одни и те же индексы , которые создаются в Old-Data
БД, будут запросы хорошо выполнять на UNION-ALL Просмотров ? Какой типа шаблонов запросов может подножку плана выполнения для UNION-ALL Просмотров ?
Ответы:
Для удобства предположим, что
LiveDb
активная база данных называется, а активная база данных называетсяArchiveDb
LiveDb
указания на таблицы вArchiveDb
базе данных через синоним (нет необходимости делать объединенные БД с синонимами)visit.date
и включите этот столбец,visit_payments
если его там еще нет (это улучшает производительность совместного размещения)LiveDb
чтобы все объединения с меньшими таблицами оставались локальнымиLiveDb
и оноArchiveDb
описывает диапазон,visit.date
содержащийся в таблице. Это помогает оптимизатору исключить архивную таблицу как из поиска, так и из сканирования, содержащего столбецvisit.data
. Вам придется периодически обновлять это ограничение.visit.data
. Это в дополнение к подсказке, которую вы уже указали в проверочном ограничении. Это максимизирует вероятность сдавливания фильтровAchiveDb
в простой режим восстановления, если это еще не сделано. Вам вряд ли понадобятся резервные копии журнала транзакцийArchiveDb
LiveDb
иArchiveDb
Все вышеперечисленное не гарантирует, что оптимизатор исключит архивные таблицы из поиска и сканирования, но повышает вероятность этого.
Когда устранение не происходит. Это эффект, который вы можете увидеть (этот список может быть неполным). Для запросов вы получите дополнительный запрос на каждый запрос (это увеличивает количество операций ввода-вывода в секунду). В случае сканирования результаты могут иметь катастрофические последствия для производительности, поскольку в итоге вы можете сканировать как архивные, так и живые таблицы. Вот типичные способы, которыми вы можете отключить оптимизатор:
visit%
таблицы вместе и не включаетеvisit.data
в критерии объединения (именно поэтому вы хотите денормализовать). Из-за этого вы можете изменить некоторые из ваших запросов.visit.data
другой таблицей (например, измерением даты), вы можете не получить правильное исключение таблицvisit.data
, например, поиск непосредственно по ключу представления.Для последнего сценария вы можете защитить себя от наихудших эффектов, добавив еще одно проверочное ограничение на
cid
- если это возможно. Вы упомянули, что последовательностьcid
не «чиста» по отношению к датам и последовательности строк в таблице. Тем не менее, не могли бы вы вести таблицу, которая содержит информацию: «Там нетcid
выше этого числа с тех порvisit.data
» или аналогичные? Это может привести к дополнительным ограничениям.Еще одна вещь, о которой следует быть осторожным, состоит в том, что параллельные запросы могут порождать ОЧЕНЬ больше потоков, когда вы запрашиваете секционированное представление (так как обе «вложенные таблицы» будут подвергаться одинаковой параллельной оптимизации). По этой причине вы можете захотеть ограничить MAXDOP на сервере или параллельные запросы.
Кстати, если вы хорошо знаете запросы - вам могут даже не понадобиться одинаковые индексы в двух базах данных (это предполагает, что вы на 100% уверены, что получите правильное исключение таблиц). Вы могли бы даже рассмотреть возможность использования хранилищ столбцов для
ArchiveDb
.источник
То, как мы это сделали, - это записать старые данные в пакетном режиме во вновь созданную базу данных и удалить старые данные из оперативной базы данных. Таким образом, оба БД доступны. Вы также можете создать резервную копию только что созданной базы данных и восстановить ее в другом месте, чтобы удалить большой объем с рабочих серверов. Надеюсь, что это приемлемое решение для ваших нужд.
источник