La cuestión:
Tenemos un sitio social donde los miembros pueden clasificarse entre sí por compatibilidad o coincidencia. Esta user_match_ratings
tabla contiene más de 220 millones de filas (9 datos de conciertos o casi 20 conciertos en índices). Las consultas en esta tabla aparecen de forma rutinaria en slow.log (umbral> 2 segundos) y es la consulta lenta registrada con más frecuencia en el sistema:
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;"
Versión de MySQL:
- versión de protocolo: 10
- versión: 5.0.77-log
- versión bdb: Sleepycat Software: Berkeley DB 4.1.24: (29 de enero de 2009)
- máquina de compilación de versiones: x86_64 versión_compilación_os: redhat-linux-gnu
Información de la mesa:
SHOW COLUMNS FROM user_match_ratings;
Da:
╔═══════════════╦════════════╦════╦═════╦════════╦════════════════╗
║ 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 ║ ║
╚═══════════════╩════════════╩════╩═════╩════════╩════════════════╝
Consulta de muestra:
select * from mutual_match_ratings where id=221673540;
da:
╔═══════════╦═══════════════╦═══════════════╦════════╦══════════════════════╗
║ id ║ rater_user_id ║ rated_user_id ║ rating ║ created_at ║
╠═══════════╬═══════════════╬═══════════════╬════════╬══════════════════════╣
║ 221673540 ║ 5699713 ║ 3890950 ║ N ║ 2013-04-09 13:00:38 ║
╚═══════════╩═══════════════╩═══════════════╩════════╩══════════════════════╝
Índices
La tabla tiene 3 índices configurados:
- índice único en
rated_user_id
- índice compuesto en
rater_user_id
ycreated_at
- índice compuesto en
rated_user_id
yrater_user_id
muestra el índice de user_match_ratings;
da:
╔════════════════════╦════════════╦═══════════════════════════╦══════════════╦═══════════════╦═══════════╦═════════════╦══════════╦════════╦═════════════════════════╦════════════╦══════════════════╗
║ 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 ║ ║ ║
╚════════════════════╩════════════╩═══════════════════════════╩══════════════╩═══════════════╩═══════════╩═════════════╩══════════╩════════╩═════════════════════════╩════════════╩══════════════════╝
Incluso con los índices, estas consultas son lentas.
Mi pregunta:
¿Separar esta tabla / datos en otra base de datos en un servidor que tenga suficiente memoria RAM para almacenar estos datos en la memoria aceleraría estas consultas? ¿Hay alguna forma de configurar las tablas / índices que podamos mejorar para agilizar estas consultas?
Actualmente tenemos 16GB de memoria; sin embargo, estamos buscando actualizar la máquina existente a 32 GB o agregar una nueva máquina con al menos esa cantidad, tal vez unidades de estado sólido también.
SELECT QUERY
. ¿Podría sugerirme? PD: Tu pregunta me obligó a unirme a esta comunidad (y);)