MySQL Partitioning: Есть ли компромисс между производительностью и количеством разделов?

10

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

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

robguinness
источник

Ответы:

6

Давайте сравним их

РАЗМЕР РАЗДЕЛА

Если у вас есть следующее:

  • 100 миллионов строк в таблице
  • BTREE индексация
  • Каждая страница в BTREE содержит 1024 ключа

Как будут выглядеть метрики?

Поскольку LOG (100000000) / LOG (2) = 26,575424759099, индекс BTREE с 1024 ключами на триоде страницы будет иметь высоту дерева всего 3 (CEILING (LOG (100000000) / LOG (1024))). При наличии только трех узлов страниц двоичный поиск необходимого ключа в каждом доступном триоде привел бы к сокращению и изоляции около 30 ключей.

КОЛИЧЕСТВО РАЗДЕЛЕЙ

Если у вас есть следующее:

  • 100 миллионов строк в таблице
  • BTREE индексация
  • Каждая страница в BTREE содержит 1024 ключа
  • Вы создаете 1024 партиции

Числа будут немного отличаться.

Каждый раздел должен иметь около 97656 строк. Какими будут метрики сейчас?

Поскольку LOG (97656) / LOG (2) = 16,575421065795, индекс BTREE с 1024 ключами на триоде страницы будет иметь высоту дерева всего 2 (CEILING (LOG (97656) / LOG (1024))). При наличии только двух узлов страниц двоичный поиск необходимого ключа в каждом доступном триоде привел бы к сокращению и изоляции около 20 ключей.

ЗАКЛЮЧЕНИЕ

Распределение ключей просто удаляет один уровень дерева, но по существу создает 1024 индекса. Запросы не будут знать разницу. Время поиска, вероятно, будет в лучшем случае номинальным в пользу разделов. Однако убедитесь, что все данные активны. Иными словами, вы можете использовать только несколько разделов, в то время как другие разделы с редко используемыми данными занимают место и никогда не используются достаточно часто, чтобы оправдать разбиение . У вас могут быть разные показатели производительности, которые могут вызывать беспокойство, такие как внутренняя дефрагментация в XFS , ext3 или ext4 и т. Д.) Вам также нужно беспокоиться о том, какой механизм хранения вы используете, потому что:

  • Индексирование InnoDB будет немного сложнее по сравнению с MyISAM из-за необходимости управлять кластерным индексом
  • InnoDB выполняет двойную запись данных в ibdata1, а также в текущий файл журнала (ib_logfile0 или ib_logfile1)
RolandoMySQLDBA
источник
1
Спасибо, RolandoMySQLDBA, это очень интересно. Из этого я понимаю, что разбиение будет иметь небольшое, но заметное положительное влияние на скорость запросов, но может иметь и другие отрицательные последствия, такие как фрагментация. Однако меня интересует, как определить оптимальное количество разделов. Должен ли я всегда использовать максимально допустимое число (например, 1024), или какой-то другой номер может быть хорошим компромиссом между положительными и отрицательными эффектами? Или не представляется возможным проанализировать этот вид оптимизации?
Робиннес
Кстати, эта статья предполагает, что ответ немного сложнее: mysqlperformanceblog.com/2010/12/11/…
robguinness
Ответ хороший, но речь идет о поиске по ключу (или проиндексированному полю). У меня нет большого опыта работы с разделами, но, с моей точки зрения, это полезно, когда вам нужно выполнить полное сканирование таблиц. В этом случае вы сканируете только несколько разделов вместо всей таблицы.
Вишня