PARTITION BY RANGE(YEAR(updated))
SUBPARTITION BY HASH(status)
SUBPARTITIONS 4 (
PARTITION p0 VALUES LESS THAN (2000),
PARTITION p1 VALUES LESS THAN (2010),
PARTITION p2 VALUES LESS THAN MAXVALUE
);
Количество SUBPARTITIONS (в примере 4) равно количеству различных значений поля status.
Скорее всего, не всё табличное пространство помещается в памяти и часть страниц InnoDB подкачивает с диска.
Советы:
* Снижайте количество "rows" в выводе explain, для этого воспользуйтесь покрывающим индексом.
* Увеличьте параметр innodb_buffer_pool_size
select t1.*
from tt as t1
inner join (
select max(id) as max_id
from tt
where fk_id in (2,4,5)
group by fk_id
) as t2 on t1.id = t2.max_id
order by fk_id;
select user_id, group_concat(distinct info_id order by info_id asc) as _i
from user_info where info_id between 1 and 3 group by user_id
having _i = '1,2,3';
В отличие от предложенного выше варианта, для этого запроса неважна уникальность связки user_id, info_id.
Можете попробовать добавить составной ключ из (param, g_id, x, y). Это немного ускорит выполнение запроса. Но при планируемых объёмах вы не сможете получить очень быструю выборку, т.к. агрегирующие функции должны пройтись по каждой записи из результата (и это даст вам Using temporary и Using filesort в explain). Советую вам либо использовать кеширование (заранее один раз подождать долгий запрос, потом N минут использовать результат), либо посмотреть в сторону MongoDB и MapReduce.