Питання:
У нас є соціальний сайт, де члени можуть оцінювати один одного за сумісність або відповідність. Ця 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-лог
- версія bdb: Програмне забезпечення Sleepycat: Berkeley 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 Ваше запитання змусило мене приєднатися до цієї спільноти (y);)