Очень большие таблицы в SQL Server - PullRequest
9 голосов
/ 24 марта 2009

У нас очень большая таблица (> 77 миллионов записей и растет), работающая на 64-битной стандартной версии SQL Server 2005, и мы наблюдаем некоторые проблемы с производительностью. Ежедневно добавляется до ста тысяч записей.

Кто-нибудь знает, существует ли ограничение на количество записей, которые может обрабатывать SQL-сервер Standard edition? Следует подумать о переходе на версию Enterprise или есть какие-то приемы, которые мы можем использовать?

Дополнительная информация:

Таблица, о которой идет речь, довольно плоская (14 столбцов), есть кластерный индекс с 6 полями и два других индекса по отдельным полям.

Мы добавили четвертый индекс, используя 3 поля, которые были выбраны в одном проблемном запросе, и не увидели никакой разницы в оценочной производительности (запрос является частью процесса, который должен выполняться в нерабочее время, поэтому мы не метрики пока нет). Эти поля являются частью кластерного индекса.

Ответы [ 10 ]

9 голосов
/ 26 марта 2009

Согласие с Marc и Unkown выше ... 6 индексов в кластерном индексе - это слишком много, особенно для таблицы, которая имеет только 14 столбцов. У вас не должно быть больше 3 или 4, если это, я бы сказал, 1 или 2. Возможно, вы знаете, что кластеризованный индекс - это фактическая таблица на диске, поэтому при вставке записи ядро ​​базы данных должно ее отсортировать и Поместите его в упорядоченное место на диске. Некластеризованные индексы не являются, они поддерживают поиск таблиц. Мои VLDB размещены на диске (CLUSTERED INDEX) в соответствии с 1-м пунктом ниже.

  1. Уменьшите свой кластеризованный индекс до 1 или 2. Лучший выбор полей - это IDENTITY (INT), если он у вас есть, или поле даты, в котором поля добавляются в базу данных, или какое-либо другое поле, которое является естественный вид того, как ваши данные добавляются в базу данных. Дело в том, что вы пытаетесь сохранить эти данные в нижней части таблицы ... или разместить их на диске наилучшим образом (более 90%), чтобы вы могли прочитать записи. Это делает так, чтобы не происходила реорганизация или что требуется один-единственный удар, чтобы получить данные в нужном месте для лучшего чтения. Обязательно поместите удаленные поля в некластеризованные индексы, чтобы не потерять эффективность поиска. Я НИКОГДА не помещал более 4 полей в мои VLDB. Если у вас есть поля, которые часто обновляются, и они включены в ваш кластеризованный индекс, OUCH, это приведет к реорганизации записи на диске и вызовет COSTLY-фрагментацию.
  2. Проверьте коэффициент заполнения по вашим индексам. Чем больше коэффициент заполнения (100), тем полнее будут страницы данных и страницы индекса. В зависимости от того, сколько записей у вас есть и сколько записей вы вставляете, вы измените коэффициент заполнения # (+ или -) ваших некластеризованных индексов, чтобы обеспечить пространство для заполнения при вставке записи. Если вы измените свой кластеризованный индекс на последовательное поле данных, это не будет иметь большого значения для кластерного индекса. Эмпирическое правило (IMO), коэффициент заполнения 60-70 для высокой записи, 70-90 для средней записи и 90-100 для высокой записи / низкой записи. Снижение коэффициента заполнения до 70 означает, что на каждые 100 записей на странице записывается 70 записей, что оставляет свободное место в 30 записей для новых или реорганизованных записей. Съедает больше места, но это наверняка превосходит необходимость дефрагментации каждую ночь (см. 4 ниже)
  3. Убедитесь, что статистика существует в таблице. Если вы хотите использовать базу данных для создания статистики, используя "sp_createstats 'indexonly", то SQL Server создаст всю статистику по всем индексам, которые накопил механизм, как требующие статистики. Не исключайте атрибут «indexonly», иначе вы добавите статистику для каждого поля, тогда это не будет хорошо.
  4. Проверьте таблицу / индексы, используя DBCC SHOWCONTIG, чтобы увидеть, какие индексы наиболее фрагментированы. Я не буду вдаваться в подробности, просто знайте, что вам нужно это сделать. Затем, основываясь на этой информации, измените коэффициент заполнения вверх или вниз относительно изменений, которые испытывают индексы, и как быстро (с течением времени).
  5. Установите расписание заданий, которое будет выполняться в режиме онлайн (DBCC INDEXDEFRAG) или в автономном режиме (DBCC DBREINDEX) для отдельных индексов, чтобы выполнять их дефрагментацию. Предупреждение: не делайте DBCC DBREINDEX для этой большой таблицы, если она не выполняется во время обслуживания, потому что это приведет к отключению приложений ... особенно в CLUSTERED INDEX. Вы были предупреждены. Протестируйте и протестируйте эту часть.
  6. Используйте планы выполнения, чтобы увидеть, какие существуют СКАНЕРЫ и ЖИРНЫЕ ТРУБЫ, и откорректировать индексы, затем дефрагментировать и перезаписать сохраненные процедуры, чтобы избавиться от этих горячих точек. Если вы видите КРАСНЫЙ объект в вашем плане выполнения, это потому, что в этом поле нет статистики. Это плохо. Этот шаг - скорее «искусство, чем наука».
  7. В непиковое время запустите UPDATE STATISTICS WITH FULLSCAN, чтобы предоставить обработчику запросов как можно больше информации о распределении данных. В противном случае выполняйте стандартную СТАТИСТИКУ ОБНОВЛЕНИЯ (со стандартным 10% -ным сканированием) для таблиц в будние дни или чаще, если вы считаете нужным свои наблюдения, чтобы убедиться, что механизм имеет больше информации о распределениях данных для эффективного извлечения данных.

Извините, это так долго, но это очень важно. Я только дам вам здесь минимальную информацию, но очень помогу. Есть некоторые интуитивные чувства и наблюдения, которые относятся к стратегиям, используемым этими пунктами, которые потребуют вашего времени и тестирования.

Нет необходимости переходить на версию Enterprise. Я сделал для того, чтобы получить функции, о которых говорилось ранее, с разделением. Но я сделал ОСОБЕННО, чтобы иметь намного лучшие возможности многопоточности с поиском и онлайн-дефрагментацией и обслуживанием ... В редакции Enterprise, это намного лучше и более дружелюбно с VLDB. Стандартная версия также не поддерживает DBCC INDEXDEFRAG с онлайн-базами данных.

7 голосов
/ 24 марта 2009

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

Для этого вам не нужно переходить на корпоративную версию.

5 голосов
/ 25 марта 2009

[есть кластерный индекс с 6 полями и два других индекса по отдельным полям.]

Не зная каких-либо подробностей о полях, я бы попытался найти способ уменьшить кластеризованный индекс.

В SQL Server все поля кластеризованного ключа также будут включены во все некластеризованные индексы (как способ сделать окончательный поиск от некластеризованного индекса до реальной страницы данных).

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

Для кластеризованного индекса абсолютно НЕОБХОДИМО, чтобы он был уникальным, стабильным и как можно меньшим (предпочтительно один INT или такой).

Марк

5 голосов
/ 24 марта 2009

Вам действительно нужен доступ ко всем 77 миллионам записей в одной таблице?

Например, если вам нужен только доступ к данным за последние X месяцев, то вы можете рассмотреть возможность создания стратегии архивирования. Это может быть использовано для перемещения данных в архивную таблицу, чтобы уменьшить объем данных и, следовательно, время запроса вашей «горячей» таблицы.

Этот подход может быть реализован в стандартной редакции.

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

Вот отличная Белая книга по разбиению таблиц в SQL Server 2005

http://msdn.microsoft.com/en-us/library/ms345146.aspx

Надеюсь, то, что я подробно изложил, ясно и понятно. Пожалуйста, не стесняйтесь связаться со мной напрямую, если вам нужна дополнительная помощь.

Приветствия

4 голосов
/ 24 марта 2009

http://msdn.microsoft.com/en-us/library/ms143432.aspx

У тебя есть место для роста.

Что касается проблем с производительностью, это совсем другой вопрос. Кэширование, шардинг, нормализация, индексирование, настройка запросов, настройка кода приложения и т. Д.

1 голос
/ 11 октября 2011

возможно это мелкие гниды, но .... (1) реляционные базы данных не имеют полей ... они имеют столбцы. (2) Столбцы IDENTITY обычно означают, что данные не нормализованы (или разработчик был ленивым). Некоторая комбинация столбцов ДОЛЖНА быть уникальной (и эти столбцы составляют первичный ключ) (3) индексация столбцов даты и времени обычно является плохой идеей; CLUSTERING для столбцов datetime также обычно является плохой идеей, особенно для постоянно увеличивающегося столбца datetime, поскольку все вставки конкурируют за одинаковое физическое пространство на диске. Кластеризация столбцов даты и времени в доступной только для чтения таблице, где этот столбец является частью ограничений диапазона, часто является хорошей идеей (посмотрите, как конфликтуют идеи?

1 голос
/ 24 марта 2009

77M записей само по себе не много для SQL Server. Как вы загружаете 100 000 записей? это ежедневная загрузка? или через какое-то приложение OLTP? и это проблема с производительностью, то есть добавление данных? или это вопрос, который доставляет вам больше всего проблем?

Если вы добавляете 100К записей за раз, а добавляемые записи вынуждают кластерный индекс переорганизовывать вашу таблицу, это быстро снизит вашу производительность. Дополнительные сведения о структуре таблицы, индексах и типе вставленных данных помогут.

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

1 голос
/ 24 марта 2009

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

Помимо этого, вы можете рассмотреть возможность разделения таблицы. Это позволит вам разделить таблицу на несколько логических групп. Вы можете сделать это «за кулисами», чтобы он по-прежнему отображался на сервере sql как одна таблица, даже если он хранится отдельно, или вы можете сделать это вручную (создать новую «архивную» или годовую таблицу и вручную перемещаться по строкам) , В любом случае, делайте это только после , сначала вы рассматривали другие варианты, потому что, если вы не сделаете это правильно, вам все равно придется проверять каждый раздел. Кроме того: для разделения требуется , требуется Enterprise Edition , так что это еще одна причина, чтобы сохранить это для последнего средства.

0 голосов
/ 25 марта 2009

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

Уникальность не требуется для кластеризованного индекса. На самом деле, лучшими кандидатами для полей, которые должны быть в кластерном индексе, являются те, которые не являются уникальными и используются в соединениях. Например, в таблице Persons, где каждый Person принадлежит одному Group, и вы часто присоединяете Persons к Groups, а при доступе к группам людей по группе Person.group_id будет идеальным кандидатом этот конкретный вариант использования.

0 голосов
/ 24 марта 2009

Какие у вас диски?

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

Вы можете переместить эту таблицу на другой диск, поместив ее в другую файловую группу. Тоже самое можно и с индексами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...