Каков наилучший способ разбить большие таблицы на SQL Server?
В недавнем проекте "ведущий" разработчик разработал схему базы данных, где "большие" таблицы будут разделены на две отдельные базы данных с представлением о основной базе данных, которая объединила бы две отдельные таблицы базы данных. Основная база данных - это то, что приложение было отключено, поэтому эти таблицы выглядели и воспринимались как обычные таблицы (за исключением некоторых причудливых вещей вокруг обновления). Это казалось огромной проблемой производительности. Мы видим проблемы с производительностью вокруг этих таблиц, но ничто не заставило его изменить свое мнение о его дизайне. Просто интересно, что это лучший способ сделать это, или если это даже стоит делать?
Ответы
Ответ 1
Я не думаю, что вы действительно получите что угодно, разделив таблицу на несколько баз данных на одном сервере. Все, что вы по существу сделали, увеличило накладные расходы при работе с "таблицей" в первую очередь, имея несколько экземпляров (т.е. Открытые в двух разных БД) из них под одним экземпляром SQL Server.
Насколько большой набор данных у вас есть? У меня есть клиент с 6-миллионной таблицей строк в SQL Server, который содержит данные о продажах за 2 года. Они используют его транзакционно и для отчетности без каких-либо проблем с производительностью.
Настройка индексов и выбор правильного кластеризованного индекса имеют решающее значение для выполнения курса.
Если ваш набор данных действительно большой, и вы хотите разбить его, вы получите больше шансов для вашего buck, разбивающего таблицу на физические серверы.
Ответ 2
Разделение не является чем-то, что нужно предпринять легкомысленно, так как может быть много тонких последствий для производительности.
Мой первый вопрос заключается в том, что вы просто ссылаетесь на размещение больших объектов таблицы в отдельных файловых группах (на отдельных шпинделях) или ссылаетесь на разделение данных внутри объекта таблицы?
Я подозреваю, что описанная ситуация - попытка сохранить физическое хранение некоторых больших таблиц на разных шпинделях из остальных таблиц. В этом случае добавление дополнительных накладных расходов в отдельных базах данных, потеряв любую способность обеспечить ссылочную целостность в базах данных, а также последствия для безопасности включения межсетевого взаимодействия с базами данных не дают никакой пользы от использования нескольких файловых групп в одной базе данных. Если, насколько это возможно, отдельные базы данных, на которые вы ссылаетесь в своем вопросе, даже не хранятся на отдельных шпинделях, но все они хранятся на одном шпинделе, тогда вы отрицаете даже небольшое преимущество в производительности, которое вы могли бы получить, физически отделяя активность вашего диска и не получили абсолютно никакой пользы.
Я бы предложил вместо использования дополнительных баз данных для хранения больших таблиц, которые вы просматриваете в разделе Filegroup в электронной документации по SQL Server или для быстрого обзора, см. в этой статье: http://www.mssqltips.com/tip.asp?tip=1112.
Если вас интересует разбиение данных (в том числе разделение на несколько групп файлов), я рекомендую прочитать статьи Кимберли Триппа, который дал отличную презентацию в то время, когда SQL Server 2005 рассказал о доступных там улучшениях. Хорошим местом для начала является этот технический документ: http://www.sqlskills.com/resources/Whitepapers/Partitioning%20in%20SQL%20Server%202005%20Beta%20II.htm.
Ответ 3
Какую версию SQL Server вы используете? SQL Server 2005 имеет секционированные таблицы, но в 2000 (или 7.0) вам нужно было использовать представления разделов.
Кроме того, что было причиной размещения разделов таблицы в отдельной базе данных?
Когда мне приходилось разбивать таблицы в прошлом (до 2005 года), обычно это столбец даты или что-то подобное, с представлением по различным разделам. В книге онлайн есть раздел, в котором рассказывается о том, как это сделать и о всех правилах вокруг него. Вы должны следовать правилам, чтобы заставить его работать, как он должен работать.
Важно помнить, что ваш столбец разделов должен быть частью первичного ключа, и вы хотите всегда использовать этот столбец при любом доступе к таблице, чтобы оптимизатор мог игнорировать разделы, на которые не должно влиять запрос.
Посмотрите "секционированную таблицу" в MSDN и вы сможете найти более полное руководство для секционированных таблиц SQL Server 2005, а также советы о том, как настроить их для максимальной производительности.
Ответ 4
Вы спрашиваете о лучших практиках с точки зрения дизайна базы данных или убеждаете, что ваше побуждение изменило его мнение?:)
С точки зрения дизайна... Вернувшись в старые добрые времена, иногда понадобилось вертикальное разбиение, чтобы обойти ограничения для движка базы данных, где количество столбцов в таблице было жестким пределом, например 255 столбцов. В наши дни основные преимущества сводятся исключительно к производительности: ставят редко используемые столбцы или капли на отдельный дисковый массив. Но если вы регулярно вытаскиваете вещи из обеих таблиц, это, скорее всего, будет потерей. Похоже, ваше лидерство страдает от случая преждевременной оптимизации.
С точки зрения того, что ваше лидерство неверно, это требует дипломатии. Если он знает о нарушениях недовольства с точки зрения производительности, то, пожалуй, наилучшим способом показать разницу может быть эталон.
Создайте новую физическую таблицу где-нибудь с "create table t1 as select * from view1", а затем запустите некоторую длинную партию с таблицей с вертикальным разделением и вашей новой таблицей. Если это так плохо, как вы говорите, разница должна быть очевидной.
Но это тоже может быть преждевременной оптимизацией. Узнайте, что конечные пользователи думают о производительности. Если производительность достаточно хорошая, для некоторого определения товара, то не фиксируйте то, что не сломалось.
Ответ 5
Существует определенная польза для разбиения таблиц (независимо от того, находится ли она на одинаковых или разных файловых группах/дисках). Если столбец разделов правильно выбран, вы поймете, что ваши запросы попадут только в требуемый раздел. Представьте себе, если у вас есть 100 миллионов записей (я разделял таблицы намного больше, чем это - около 20 + миллиардов строк), и если в большинстве случаев более 70% вашего доступа к данным - это только определенная категория или временная шкала или тип данных то он помогает хранить наиболее доступные данные в отдельном разделе. Кроме того, вы можете выровнять раздел с отдельными файловыми группами с различными типами дисков (SATA, Fibre Channel, SSD), чтобы наиболее доступные/занятые данные находились на самом быстром хранении, а наименее/редкий доступ - практически на более медленных дисках.
Несмотря на то, что в SQL Server существует ограниченная возможность разделения, в отличие от Oracle. Вы можете выбрать только один столбец для разбиения (даже в sql 2008). Таким образом, вы должны выбрать графу мудро, где этот столбец также является частью большинства ваших частых запросов. В большинстве случаев людям легко выбрать разбиение по столбцу даты. Однако, хотя кажется логичным разделить этот путь, если ваши запросы не имеют этого столбца как часть условия, вы не получите достаточных преимуществ от секционирования (другими словами, ваш запрос попадет во все разделы независимо).
Гораздо проще разбивать базы данных типа datawarehouse/data mining, чем OLTP, поскольку большинство запросов к базе данных DW ограничены периодом времени.
Итак, почему в наши дни из-за объема данных, обрабатываемых базами данных, разумно разрабатывать приложение таким образом, чтобы когда-либо запрос ограничивался некоторой более широкой группой, такой как время, географическое местоположение или такое, что когда такие столбцы выбраны для разделения, вы получите максимальные преимущества.
Ответ 6
Я бы не согласился с предположением, что ничего не может быть достигнуто при разбиении.
Если данные раздела физически и логически выровнены, то потенциальный IO запросов должен быть значительно уменьшен.
Например: у нас есть таблица, которая имеет пакетное поле как INT, представляющее INT.
Если мы разделяем данные по этому полю, а затем повторно запускаем запрос для определенной партии, мы должны иметь возможность запускать статистику набора io ON до и после секционирования и видеть уменьшение IO,
Если у нас есть миллион строк на раздел, и каждый раздел записывается на отдельное устройство. Запрос должен иметь возможность исключить ненужные разделы.
Я не делал много секционирования на SQL Server, но у меня есть опыт разделения на Sybase ASE, и это известно как устранение разделов. Когда у меня будет время, я собираюсь проверить сценарий на машине SQL Server 2005.