Проблема оптимизации запросов ввода-вывода, связанная с MySQL, без установки innodb_buffer_pool_size в 5 ГБ - PullRequest
2 голосов
/ 10 апреля 2011

Я столкнулся с проблемой масштабируемости дизайна MySQL.Любая помощь будет принята с благодарностью.

Требования:

Хранение пользовательских SOCIAL_GRAPH и USER_INFO для каждого пользователя в их социальной графе.Происходит много одновременных операций чтения и записи в секунду.Грязное чтение приемлемо.

Текущий дизайн:

У нас есть 2 (соответствующие) таблицы.Оба InnoDB для блокировки строк вместо блокировки таблиц.

  1. USER_SOCIAL_GRAPH таблица, которая отображает вошедший в систему (user_id) с другим (related_user_id).Составной ключ PRIMARY user_id и related_user_id.

  2. USER_INFO таблица с информацией о каждом связанном пользователе.ПЕРВИЧНЫЙ ключ: (related_user_id).

Примечание 1. Отношения не определены.

Примечание 2. Каждая таблица теперь имеет размер около 1 ГБ, с 8 миллионами и 2 миллионамизаписи соответственно.

Упрощенная таблица SQL создает:

CREATE TABLE `user_social_graph` (
  `user_id` int(10) unsigned NOT NULL,
  `related_user_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`related_user_id`),
  KEY `user_idx` (`user_id`)
) ENGINE=InnoDB;

CREATE TABLE `user_info` (
  `related_user_id` int(10) unsigned NOT NULL,
  `screen_name` varchar(20) CHARACTER SET latin1 DEFAULT NULL,
  [... and many other non-indexed fields irrelevant]
  `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`related_user_id`),
  KEY `last_updated_idx` (`last_updated`)
) ENGINE=InnoDB;

Установленные значения MY.CFG:

innodb_buffer_pool_size = 256M
key_buffer_size         = 320M

Примечание 3:Доступная память 1 ГБ, эти 2 таблицы - 2 ГБ, другие таблицы innoDB - 3 ГБ.

Проблема:

В следующем примере SQL-оператора, которому требуется доступ ко всем найденным записям, требуется15 секунд для выполнения (!!) и num_results = 220 000:

SELECT SQL_NO_CACHE COUNT(u.related_user_id) 
FROM user_info u LEFT JOIN user_socialgraph u2 ON u.related_user_id = u2.related_user_id 
WHERE u2.user_id = '1' 
AND u.related_user_id = u2.related_user_id 
AND (NOT (u.related_user_id IS NULL));

Для user_id со счетом 30 000 требуется около 3 секунд (!).

ОБЪЯСНИТЬ, РАСШИРЕНО для220 000 пользователей.Используются индексы:

+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
| id | select_type | table | type   | possible_keys          | key      | key_len | ref                | rows   | filtered | Extra                    |
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
|  1 | SIMPLE      | u2    | ref    | user_user_idx,user_idx | user_idx | 4       | const              | 157320 |   100.00 | Using where              |
|  1 | SIMPLE      | u     | eq_ref | PRIMARY                | PRIMARY  | 4       | u2.related_user_id |      1 |   100.00 | Using where; Using index |
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+

Как мы можем ускорить их, не устанавливая innodb_buffer_pool_size в 5 ГБ?

Спасибо!

Ответы [ 2 ]

1 голос
/ 10 апреля 2011

Таблица user_social_graph неправильно проиндексирована !!!

У вас есть ths:

CREATE TABLE user_social_graph
(user_id int (10) unsigned NOT NULL,
related_user_id int (11) NOT NULL,
ПЕРВИЧНЫЙ КЛЮЧ (user_id, related_user_id),
KEY user_idx (user_id))
ENGINE = InnoDB;

Второй индекс является избыточным, поскольку первый столбец - user_id.Вы пытаетесь присоединить столбец related_user_id к таблице user_info.Этот столбец необходимо проиндексировать.

Измените user_social_graphs следующим образом:

CREATE TABLE user_social_graph
(user_id int (10) без знака NOT NULL,
related_user_idint (11) NOT NULL,
ПЕРВИЧНЫЙ КЛЮЧ (user_id, related_user_id),
УНИКАЛЬНЫЙ КЛЮЧ related_user_idx (related_user_id, user_id))
ENGINE = InnoDB;

Это должно изменить ПЛАН ОБЪЯСНЕНИЯ.Помните, что порядок индексов имеет значение в зависимости от того, как вы запрашиваете столбцы.

Дайте ему попытку !!!

0 голосов
/ 11 апреля 2011
  1. Что такое версия MySQL?Его руководство содержит важную информацию для ускорения операторов и кода в целом;

  2. Измените вашу парадигму на хранилище данных, способное управлять до терабайтной таблицы.Перенесите устаревшую базу данных MySQL с помощью бесплатного инструмента или приложения на новую парадигму.Вот пример: http://www.infobright.org/Downloads/What-is-ICE/ многие другие (бесплатные и коммерческие).

  3. PostgreSQL не является коммерческим, и существует множество инструментов для миграции на него MySQL!

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