Я столкнулся с проблемой масштабируемости дизайна MySQL.Любая помощь будет принята с благодарностью.
Требования:
Хранение пользовательских SOCIAL_GRAPH и USER_INFO для каждого пользователя в их социальной графе.Происходит много одновременных операций чтения и записи в секунду.Грязное чтение приемлемо.
Текущий дизайн:
У нас есть 2 (соответствующие) таблицы.Оба InnoDB для блокировки строк вместо блокировки таблиц.
USER_SOCIAL_GRAPH таблица, которая отображает вошедший в систему (user_id) с другим (related_user_id).Составной ключ PRIMARY user_id и related_user_id.
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 ГБ?
Спасибо!