SQL большой дизайн таблицы

17

У меня есть общий вопрос о дизайне таблиц SQL Server 2008. В настоящее время у нас есть таблица, которая превышает 600 ГБ и растет примерно на 3 ГБ в день. Эта таблица имеет соответствующие значения, но становится серьезным зависанием при выполнении запросов и только из-за ее размера. Вопрос в том, должен ли я разделить таблицу на несколько таблиц по годам и месяцам (это будет соответствовать тому, как другие отделы разбивают свои большие наборы данных) или нам следует использовать разделение, встроенное в SQL Server. Похоже, что использование разделов потребует меньше изменений кода. Из того, что я прочитал при разбиении, вы по-прежнему просто запрашиваете одну таблицу, и сервер обрабатывает, как получить данные. Если бы мы пошли по маршруту с несколькими таблицами, нам пришлось бы обрабатывать данные из нескольких таблиц.

HunterX3
источник
1
Должны ли быть сделаны какие-либо оптимизации: слишком широкие типы данных, перекрывающиеся или неиспользуемые индексы и т. Д.?
ГБН
Возможно, я еще не заглянул за рамки других оптимизаций. У вас есть рекомендации?
HunterX3

Ответы:

11

«Эта таблица имеет соответствующие значения, но становится серьезным зависанием при выполнении запросов»

Одно только разбиение не помогает повысить производительность запросов, если только SQL Server не сможет устранить разделы при выполнении запроса. Ваше предложение WHERE должно соответствовать способу разбиения. У нас есть только одно поле для использования в качестве поля разбиения, поэтому, если это поле не включено в ваше предложение WHERE, вы все равно можете сканировать всю таблицу, несмотря на наличие разделов.

"и только из-за его размера."

Разбиение может облегчить некоторые операции обслуживания, но есть вещи, которые мы не можем сделать для каждого раздела. Если обслуживание индексов и обновления статистики вызывают у вас проблемы, лучше разбить проект на архивную таблицу и оперативно обновляемую таблицу. Когда вам нужно периодически перемещать данные из оперативной таблицы в таблицу архива, вы делаете это, перестраиваете индексы с коэффициентом заполнения 100%, обновляете статистику с полной проверкой, а затем настраиваете ее файловую группу только для чтения. Разбиение может помочь с загрузкой архивных таблиц, но разбиение оперативной таблицы может не помочь. (Я выбрасываю несколько продвинутых концепций здесь, как будто это быстро и просто, но я просто набрасываю некоторые основы здесь.)

«Похоже, что использование разделов потребует меньше изменений кода».

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

Я написал больше о подводных камнях разделения здесь:

http://www.brentozar.com/archive/2008/06/sql-server-partitioning-not-the-answer-to-everything/

Брент Озар
источник
3
Любимая цитата из этой статьи: «Функции и схемы разделов легко спроектировать неправильно».
Марк Стори-Смит
7

Разделение в отдельности может быть достаточным, но вы можете получить лучшие результаты, комбинируя с разделенными представлениями и несколькими таблицами. Это очень сильно зависит от схемы запросов и роста.

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

Если характер ваших данных меняется от месяца к месяцу, год к году, разделенные представления также могут помочь. Представьте себе розничного продавца, который постоянно менял свои продуктовые линейки, так что в Product.ProductId диапазон использования из года в год невелик. С одной таблицей order / orderdetail и, следовательно, с единой гистограммой статистики, статистика мало что даст оптимизатору запросов. Таблица за год (Order_2010, Order_2011, OrderLine_2010, OrderLine_2011), разделенная по месяцам и объединенная с разделенными представлениями (Order, OrderLine), предоставит оптимизатору более детальную и потенциально полезную статистику.

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

Кимберли Трипп опубликовал множество руководств и официальных документов по разделам , которые обычно считаются необходимыми для чтения по этой теме. У Кендры Литтл также есть хороший материал и полезный список других статей.

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

Если у вас есть неидеальный, но не редкий процесс отправки резервных копий по сети, вы можете рассчитывать на 3-часовое время восстановления для текущих 600 ГБ. Через год, когда вы преодолели 1,5 ТБ, у вас возникнут проблемы.

Марк Стори-Смит
источник
1
+1 За «статистику столбцов ведется только за столом», и я хотел бы еще раз +1 за ссылки на Кимберли и Кендру.
Мэтт М
1

Как вы сказали, у вас есть два варианта:

  1. Использовать несколько таблиц
  2. Использовать разделение

С помощью 1 вы можете создать VIEW, объединяющий все эти таблицы, и просто обновить его, чтобы включить вновь созданные таблицы. Я считаю, что это действительно способ эмулировать разбиение. Плюсы этого метода включают в себя не требующий Enterprise Edition SQL Server.

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

Если у вас есть Enterprise Edition, я бы определенно посмотрел на разделы. Несмотря на то, насколько сложным это выглядит, на самом деле все не так плохо. Если нет, разделение даже не вариант для вас.

Создание секционированных таблиц

Изменение секционированных таблиц

Проектирование разделов для управления подмножествами данных

Надеюсь это поможет,

Matt

Мэтт М
источник
0

Исходя из вашего вопроса, вы, похоже, храните исторические данные (журналы), и ваши ограничения, по-видимому, связаны со скоростью запросов, а не с проблемами с хранилищем. Для меня раздел не поможет.

Когда вы говорите, что у вас есть правильные индексы, включает ли он индекс в поле даты? У меня были хорошие результаты при использовании индекса на усеченной (метка времени, день) с Postgres. Затем вы должны убедиться, что все запросы выбираются за день до любых других манипуляций. Будьте осторожны, отметка времени с полем часового пояса не индексируется (потому что она «перемещается» в зависимости от часового пояса), поэтому для индексирования вам нужна «фиксированная» отметка времени.

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