Этот вопрос является более конкретной версией предыдущего вопроса, который я задавал
Таблица
CREATE TABLE Test4_ClusterMatches
(
`match_index` INT UNSIGNED,
`cluster_index` INT UNSIGNED,
`id` INT NOT NULL AUTO_INCREMENT,
`tfidf` FLOAT,
PRIMARY KEY (`cluster_index`,`match_index`,`id`)
);
Запрос, который я хочу выполнить
mysql> explain SELECT `match_index`, SUM(`tfidf`) AS total
FROM Test4_ClusterMatches WHERE `cluster_index` IN (1,2,3 ... 3000)
GROUP BY `match_index`;
Проблема с запросом
Он использует временную и файловую сортировку, поэтому его нужно замедлить
+----+-------------+----------------------+-------+---------------+---------+---------+------+-------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+---------------+---------+---------+------+-------+-----------------------------------------------------------+
| 1 | SIMPLE | Test4_ClusterMatches | range | PRIMARY | PRIMARY | 4 | NULL | 51540 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+----------------------+-------+---------------+---------+---------+------+-------+-----------------------------------------------------------+
При текущей индексации запрос должен будет сначала отсортировать по cluster_index, чтобы устранитьиспользование временных файлов и сортировка файлов, но это дает неверные результаты для суммы (tfidf).Изменение первичного ключа на
PRIMARY KEY (`match_index`,`cluster_index`,`id`)
Не использует сортировку файлов или временные таблицы, но использует 14 932 441 строку, поэтому оно также замедляет
+----+-------------+----------------------+-------+---------------+---------+---------+------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+---------------+---------+---------+------+----------+--------------------------+
| 1 | SIMPLE | Test5_ClusterMatches | index | NULL | PRIMARY | 16 | NULL | 14932441 | Using where; Using index |
+----+-------------+----------------------+-------+---------------+---------+---------+------+----------+--------------------------+
Tight Index Scan
Использование строгого сканирования индекса путем запуска поиска только одного индекса
mysql> explain SELECT <code>match_index</code>, SUM(<code>tfidf</code>) AS total
FROM Test4_ClusterMatches WHERE <code>cluster_index</code> =3000
GROUP BY <code>match_index</code>;
Удаляет временные таблицы и сортировку файлов.
+----+-------------+----------------------+------+---------------+---------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+------+---------------+---------+---------+-------+------+--------------------------+
| 1 | SIMPLE | Test4_ClusterMatches | ref | PRIMARY | PRIMARY | 4 | const | 27 | Using where; Using index |
+----+-------------+----------------------+------+---------------+---------+---------+-------+------+--------------------------+
Я не уверен, что это можно использовать с каким-то волшебным sql-fu, с которым я еще не сталкивался?
Вопрос
Как я могу изменить свой запрос так, чтобы он использовал 3000 cluster_indexes, избегая использования временных и файловых сортировок без необходимости использовать 14 932 441 строк?
Обновление
Использование таблицы
CREATE TABLE Test6_ClusterMatches
(
match_index INT UNSIGNED,
cluster_index INT UNSIGNED,
id INT NOT NULL AUTO_INCREMENT,
tfidf FLOAT,
PRIMARY KEY (id),
UNIQUE KEY(cluster_index,match_index)
);
Затем приведенный ниже запрос дает 10 строк в наборе (0,41 с):)
SELECT `match_index`, SUM(`tfidf`) AS total FROM Test6_ClusterMatches WHERE
`cluster_index` IN (.....)
GROUP BY `match_index` ORDER BY total DESC LIMIT 0,10;
но он использует временную и сортировку файлов
+----+-------------+----------------------+-------+---------------+---------------+---------+------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+---------------+---------------+---------+------+-------+----------------------------------------------+
| 1 | SIMPLE | Test6_ClusterMatches | range | cluster_index | cluster_index | 5 | NULL | 78663 | Using where; Using temporary; Using filesort |
+----+-------------+----------------------+-------+---------------+---------------+---------+------+-------+----------------------------------------------+
Интересно, есть ли способ получить его быстрее, исключив использование временных и использование сортировки файлов?