Разбиение MySQL и автоматическое перемещение строк

0

У меня есть таблица с ~ 6M строками, которая извлекает около 20 000-30 000 строк на запрос с оптимизацией индекса. Однако, так как многие люди последовательно извлекают эти строки (каждые 30 секунд или около того), сайт часто будет тайм-аутом для людей.

Недавно я перенес базу данных в 3-серверный кластер MySQL с огромным объемом оперативной памяти (512 ГБ на сервер), и производительность не улучшилась.

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

Мой вопрос в том, что все эти строки имеют столбец, который либо будет иметь значение 0, 1, 2 или 3.

Можно ли каким-либо образом разместить все строки со значением 1 в определенном столбце на одном разделе, а все строки со значением 2 в столбце в другом? И будут ли они автоматически перемещаться в зависимости от значения, которое обновляется в первичной таблице? И самое главное, это могло бы помочь в производительности, поскольку ему нужно было бы только просмотреть 1 ряд в 20 000-30 000 вместо 6 000 000

  • 1
    Вы рассматривали слой кэширования? Я не думаю, что одно только разделение сильно поможет с такой моделью использования, которую вы описываете. Кроме того, ваш вопрос должен отвечать, просто прочитав документы: dev.mysql.com/doc/refman/5.7/en/partitioning-types.html
  • 0
    Пожалуйста, покажите SQL, который у вас есть; твоя проза слишком расплывчата И SHOW CREATE TABLE .
Показать ещё 2 комментария
Теги:
partition

1 ответ

1

Да, MySQL поддерживает разделение. Вы можете определить разделы очень хорошо, например:

CREATE TABLE MyTable (
  id INT AUTO_INCREMENT PRIMARY KEY,
  somestuff INT,
  otherstuff VARCHAR(100),
  KEY (somestuff)
) PARTITION BY HASH(id) PARTITIONS 4;

INSERT INTO MyTable () VALUES (), (), (), ();

Вы можете проверить количество строк в каждом разделе после этого:

SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='MyTable';
+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| p0             |          1 |
| p1             |          1 |
| p2             |          1 |
| p3             |          1 |
+----------------+------------+

Тем не менее, есть две вещи, которые отключают людей, когда они пытаются использовать разбиение на разделы в MySQL:

Во-первых, https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations-partitioning-keys-unique-keys.html говорит:

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

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

ALTER TABLE MyTable PARTITION BY HASH(somestuff) PARTITIONS 4;
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table partitioning function

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

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

mysql> EXPLAIN PARTITIONS SELECT * FROM MyTable WHERE SomeStuff = 3;
+----+-------------+---------+-------------+------+---------------+-----------+---------+-------+------+-------+
| id | select_type | table   | partitions  | type | possible_keys | key       | key_len | ref   | rows | Extra |
+----+-------------+---------+-------------+------+---------------+-----------+---------+-------+------+-------+
|  1 | SIMPLE      | MyTable | p0,p1,p2,p3 | ref  | somestuff     | somestuff | 5       | const |    4 | NULL  |
+----+-------------+---------+-------------+------+---------------+-----------+---------+-------+------+-------+

Обратите внимание, что это потребует сканирования разделов p0, p1, p2, p3 - т.е. всей таблицы. Нет обрезки разделов, поэтому нет улучшения производительности, поскольку она не уменьшает количество проверенных строк.

Если вы выполняете поиск определенного значения в столбце, используемом в выражении секционирования, вы можете видеть, что MySQL может уменьшить количество просматриваемых разделов:

mysql> EXPLAIN PARTITIONS SELECT * FROM MyTable WHERE id = 3;
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table   | partitions | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | MyTable | p3         | const | PRIMARY       | PRIMARY | 4       | const |    1 | NULL  |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+-------+

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню