2010-11-22 7 views
9

У меня есть сценарий, в котором содержится огромное количество данных о состоянии элемента. Состояние предмета обновляется с минуты на минуту, и в ближайшем будущем будет около 50 000 предметов. Таким образом, через месяц будет составлено около 2 232 000 000 строк данных. Я должен держать как минимум 3 месяца в главной таблице, прежде чем архивировать старые данные.Разбиение на производительность запросов в SQL Server 2008

Я должен планировать выполнение быстрых запросов на основе определенного элемента (его идентификатора) и диапазона данных (обычно, до одного месяца) - например, выберите A, B, C из таблицы, где ItemID = 3000 и Date между '2010-10-01' и '2010-10-31 23: 59: 59.999'

Итак, мой вопрос заключается в том, как создать структуру разбиения на добиться этого?

В настоящее время я разбиваю на основе «уникальный идентификатор товара» (int) mod «количество разделов», так что все разделы распределены равномерно. Но у него есть недостаток, заключающийся в том, что один столбец таблицы должен выступать в качестве столбца раздела для функции разбиения, поэтому сопоставление строки с ее разделом. Все это добавляет немного дополнительной памяти. Кроме того, каждый раздел отображается в другую файловую группу.

+1

Это немного нагрузки. Прочитайте [здесь] (http://sqlblog.com/blogs/paul_nielsen/archive/2007/12/12/10-lessons-from-35k-tps.aspx) о записи большого объема (у вас есть 50 тыс. Строк * за второй * входящий). Я заинтригован, как вы решите это: у меня нет опыта в том, что объем/темп роста) вообще – gbn 2010-11-22 18:58:38

+0

Вы пытаетесь создать для эффективности запросов или эффективности чтения? Какие у вас читаемые грузы? – 2010-11-30 12:56:24

ответ

10

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

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

Разбиение на разделы полезно для ячеек управления путями ввода-вывода (распределение по объемам архива/тока) или для быстрых сценариев переключения в нагрузках ETL. Поэтому я бы понял, если у вас есть скользящее окно и раздел по дате, чтобы вы могли быстро отключить данные, которые больше не нужны для сохранения.

Другим узким футляром для разметки является последняя фиксация закладок страницы, как описано в Resolving PAGELATCH Contention on Highly Concurrent INSERT Workloads.

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

0

Я согласен с Remus, разметка не улучшит ситуацию, как показывают ваши собственные результаты.

Забудьте о секционировании, проиндексируйте как идентификатор, так и дату и запустите окно с огромной ОЗУ; каковы результаты?

1

Я действительно не согласен с Ремусом Русану. Я думаю, что разбиение может повысить производительность, если есть логическая причина (связанная с вашими вариантами использования). Я предполагаю, что вы можете разделить только на ItemID. Альтернативой будет также использование даты, но если вы не можете предсказать, что диапазон дат не пересечет границы данного раздела (запросы не обязательно будут с одним месяцем), тогда я бы придерживался раздела itemId.

Если вам нужно вычислить только несколько элементов, другой вариант состоит в том, чтобы иметь индекс покрытия: определить ИНДЕКС на вашем основном поле дифференциации (itemId), который ВКЛЮЧАЕТ поля, которые вам нужно вычислить.

CREATE INDEX idxTest ON itemId INCLUDE quantity; 
1

Аппликативные перегородки действительно могут быть полезными для выполнения запроса. В вашем случае у вас есть 50K предметов и 2G строк. Например, вы можете создать 500 таблиц, каждый из которых имеет имя status_nnn, где nnn находится между 001 и 500 и «разделяет» ваши статусы предметов одинаково среди этих таблиц, где nnn является функцией идентификатора элемента. Таким образом, с учетом идентификатора элемента, вы можете ограничить ваш поиск априори 0,2% от всех данных (около 4 миллионов строк).

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

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

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

Смежные вопросы