Как разделение повлияет на мои текущие запросы в MySQL?Когда пришло время разделить мои таблицы? - PullRequest
2 голосов
/ 29 марта 2019

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

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

  1. Разумно ли разделить таблицу, которую я описал, и это вероятно, улучшить его производительность?
  2. Если я сделаю это, Я должен внести изменения в мои текущие операторы INSERT или SELECT или Будут ли они продолжать работать так же?
  3. Есть ли раздел занять много времени, чтобы выполнить? Я беспокоюсь о том, что при низкой производительности что-то случится на полпути, и я потеряю данные.

  4. Должен ли я делить это на годы или месяцы? (мы обычно посмотрим на цифры в течение месяца, но иногда мы берем недели или года). И я должен также разделить столбцы? (У нас есть немного столбцы, которые мы редко или никогда не используем, но мы могли бы хотеть использовать их позже)

Ответы [ 2 ]

2 голосов
/ 30 марта 2019

В большинстве случаев лучше использовать indexes вместо разделения в качестве основного метода оптимизации запросов.

Первое, что вы должны узнать о разбиении в MySQL, это правило:

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

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

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

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

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

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

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

1 голос
/ 19 апреля 2019

(Я согласен с ответом Билла; я подойду к Вопросу по-другому.)

Когда пора разбивать мои таблицы?

Возможно, никогда.

может ли он улучшить свою производительность?

Скорее всего, немного снизится производительность.

У меня есть таблицасодержит 1,5 миллиона строк

Недостаточно большого размера, чтобы беспокоиться о разбиении.

Запросы в настоящее время занимают очень много времени

Обычно , что связано с отсутствием хорошего индекса, возможно, «составного». Во-вторых - это формулировка запроса.Пожалуйста, покажите нам медленный запрос вместе с SHOW CREATE TABLE.

данными за 2 года, и он растет каждый день

Будете ли вы в конечном итоге очищать "старые" данные?Если это так, PARTITION BY RANGE(TO_DAYS(..)) - отличная идея.Тем не менее, это помогает только во время чистки.Это потому, что DROP PARTITION на лот быстрее, чем DELETE....

у нас, вероятно, сейчас меньше памяти.

Если вы в основномесли посмотреть на «последние» данные, то размер памяти (ср innodb_buffer_pool_size) может не имеет значения.Это связано с кешированием.Тем не менее, похоже, что вы выполняете сканирование таблицы, возможно, излишне.

Придется ли мне вносить изменения в мой текущий INSERT или SELECT

Нет.Но вам , вероятно , нужно изменить столбцы в PRIMARY KEY и вторичном ключе (ключах).

Требуется ли много времени для выполнения раздела?

Медленно - да, потому что он скопирует всю таблицу.Примечание: это означает дополнительное дисковое пространство, и разделенная таблица займет больше диска.

что-то произойдет на полпути, и я потеряю данные.

Не беспокойтесь,Создается новая таблица, затем очень быстро RENAME TABLE заменяет ее на место.

Должен ли я делить ее на годы или месяцы?

Правило большого пальца:цель около 50 разделов.С "2 годами и растущими" вероятным выбором будет "ежемесячно".

мы обычно смотрим на цифры в течение месяца, но иногда мы берем недели или годы

Пахнет как типичный набор данных «Хранилище данных»?Постройте и постепенно увеличивайте «Сводную таблицу» с ежедневной статистикой.С помощью этой таблицы вы можете быстро получить еженедельную / ежемесячную / годовую статистику - возможно, в 10 раз быстрее.То же самое для любого диапазона дат.Это также значительно помогает при «нехватке памяти».

И нужно ли также разбивать столбцы?(У нас есть некоторые столбцы, которые мы используем редко или никогда, но мы могли бы использовать их позже)

Вы не должны использовать никогда SELECT *;вместо этого укажите столбцы, которые вам действительно нужны.«Вертикальное разделение» - это термин для вашего предложения.Это иногда практично.Но нам нужно увидеть SHOW CREATE TABLE с реалистичными именами столбцов для дальнейшего обсуждения.

Подробнее о разбиении: http://mysql.rjweb.org/doc.php/partitionmaint
Подробнее о сводных таблицах: http://mysql.rjweb.org/doc.php/summarytables

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