Проблема:
У нас есть социальный сайт, где участники могут оценивать друг друга для совместимости или соответствия. Эта user_match_ratings
таблица содержит более 220 миллионов строк (данные по 9 ГБ или почти 20 ГБ по индексам). Запросы к этой таблице обычно отображаются в slow.log (порог> 2 секунды) и являются наиболее часто регистрируемым медленным запросом в системе:
Query_time: 3 Lock_time: 0 Rows_sent: 3 Rows_examined: 1051
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 395357 group by rating;"
Query_time: 4 Lock_time: 0 Rows_sent: 3 Rows_examined: 1294
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 4182969 group by rating;"
Query_time: 3 Lock_time: 0 Rows_sent: 3 Rows_examined: 446
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 630148 group by rating;"
Query_time: 5 Lock_time: 0 Rows_sent: 3 Rows_examined: 3788
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 1835698 group by rating;"
Query_time: 17 Lock_time: 0 Rows_sent: 3 Rows_examined: 4311
"select rating, count(*) as tally from user_match_ratings where rated_user_id = 1269322 group by rating;"
Версия MySQL:
- версия протокола: 10
- версия: 5.0.77-log
- версия bdb: Программное обеспечение Sleepycat: Беркли DB 4.1.24: (29 января 2009 г.)
- машина компиляции версии: x86_64 version_compile_os: redhat-linux-gnu
Информация о таблице:
SHOW COLUMNS FROM user_match_ratings;
дает:
╔═══════════════╦════════════╦════╦═════╦════════╦════════════════╗
║ id ║ int(11) ║ NO ║ PRI ║ NULL ║ auto_increment ║
║ rater_user_id ║ int(11) ║ NO ║ MUL ║ NULL ║ ║
║ rated_user_id ║ int(11) ║ NO ║ MUL ║ NULL ║ ║
║ rating ║ varchar(1) ║ NO ║ ║ NULL ║ ║
║ created_at ║ datetime ║ NO ║ ║ NULL ║ ║
╚═══════════════╩════════════╩════╩═════╩════════╩════════════════╝
Пример запроса:
select * from mutual_match_ratings where id=221673540;
дает:
╔═══════════╦═══════════════╦═══════════════╦════════╦══════════════════════╗
║ id ║ rater_user_id ║ rated_user_id ║ rating ║ created_at ║
╠═══════════╬═══════════════╬═══════════════╬════════╬══════════════════════╣
║ 221673540 ║ 5699713 ║ 3890950 ║ N ║ 2013-04-09 13:00:38 ║
╚═══════════╩═══════════════╩═══════════════╩════════╩══════════════════════╝
Индексы
Таблица имеет 3 настроенных индекса:
- единый индекс на
rated_user_id
- составной индекс на
rater_user_id
иcreated_at
- составной индекс на
rated_user_id
иrater_user_id
показать индекс из user_match_ratings;
дает:
╔════════════════════╦════════════╦═══════════════════════════╦══════════════╦═══════════════╦═══════════╦═════════════╦══════════╦════════╦═════════════════════════╦════════════╦══════════════════╗
║ Table ║ Non_unique ║ Key_name ║ Seq_in_index ║ Column_name ║ Collation ║ Cardinality ║ Sub_part ║ Packed ║ Null ║ Index_type ║ Comment ║
╠════════════════════╬════════════╬═══════════════════════════╬══════════════╬═══════════════╬═══════════╬═════════════╬══════════╬════════╬═════════════════════════╬════════════╬══════════════════╣
║ user_match_ratings ║ 0 ║ PRIMARY ║ 1 ║ id ║ A ║ 220781193 ║ NULL ║ NULL ║ BTREE ║ ║ ║
║ user_match_ratings ║ 1 ║ user_match_ratings_index1 ║ 1 ║ rater_user_id ║ A ║ 11039059 ║ NULL ║ NULL ║ BTREE ║ ║ ║
║ user_match_ratings ║ 1 ║ user_match_ratings_index1 ║ 2 ║ created_at ║ A ║ 220781193 ║ NULL ║ NULL ║ BTREE ║ ║ ║
║ user_match_ratings ║ 1 ║ user_match_ratings_index2 ║ 1 ║ rated_user_id ║ A ║ 4014203 ║ NULL ║ NULL ║ BTREE ║ ║ ║
║ user_match_ratings ║ 1 ║ user_match_ratings_index2 ║ 2 ║ rater_user_id ║ A ║ 220781193 ║ NULL ║ NULL ║ BTREE ║ ║ ║
║ user_match_ratings ║ 1 ║ user_match_ratings_index3 ║ 1 ║ rated_user_id ║ A ║ 2480687 ║ NULL ║ NULL ║ BTREE ║ ║ ║
╚════════════════════╩════════════╩═══════════════════════════╩══════════════╩═══════════════╩═══════════╩═════════════╩══════════╩════════╩═════════════════════════╩════════════╩══════════════════╝
Даже с индексами эти запросы медленные.
Мой вопрос:
Будет ли разделение этой таблицы / данных в другой базе данных на сервере, на котором достаточно оперативной памяти для хранения этих данных в памяти, ускорит ли это эти запросы? Есть ли что-то в таблицах / индексах, которые мы можем улучшить, чтобы сделать эти запросы быстрее?
В настоящее время у нас есть 16 ГБ памяти; однако мы рассматриваем либо модернизацию существующей машины до 32 ГБ, либо добавление новой машины, по крайней мере, с таким большим, может быть, твердотельным накопителем.
SELECT QUERY
. Не могли бы вы предложить? PS Ваш вопрос заставил меня присоединиться к этому сообществу (у);)