Как расставить индексы в MySQL с различными сортировками?

CREATE TABLE IF NOT EXISTS `mess_sett` (
`id` int(10) unsigned NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `prew` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `man_id` int(10) unsigned NOT NULL,
  `girl_id` int(10) unsigned NOT NULL,
  `man_where` enum('inbox','outbox','') COLLATE utf8mb4_unicode_ci NOT NULL,
  `man_group` tinyint(1) NOT NULL DEFAULT '0',
  `man_saw` tinyint(1) NOT NULL DEFAULT '0',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


Всего записей 20 млн.
Выборка по `man_id` вернёт около 3000-4000 записей
Выборка по `man_id` + `man_where` оставит уже 2000-3000 записей
Выборка по `man_id` + `man_where` + `man_group` оставит уже в одном разделе 1990-2990, в другом 10 записей. (то есть по полю `man_group` отсеиваются всего 10 записей).

Запросы:
SELECT ... WHERE `man_id` = 1 AND `man_where` = 'inbox' AND `man_group` = 1 ORDER BY `id` DESC
SELECT ... WHERE `man_id` = 1 AND `man_where` = 'inbox' AND `man_group` = 1 ORDER BY `man_saw` ASC
SELECT ... WHERE `man_id` = 1 AND `man_where` = 'inbox' AND `man_group` = 1 ORDER BY `girl_id` ASC

Без составного индекса по полю сортировки во временной таблице будет сортироваться около 1000-2000 записей.
Как верно в данном случае составить индекс/индексы?

Я вот думаю:
1) Только лишь составной по
`man_id` + `man_where` + `man_group`
2) Сделать 3 составных индекса по полям:
`man_id` + `man_where` + `man_group` + `id`
`man_id` + `man_where` + `man_group` + `girl_id`
`man_id` + `man_where` + `man_group` + `man_saw`

3) Сделать 1 составной и несколько простых с надеждой, что мускул сам объединит индексы и правильно всё сделает:
`man_id` + `man_where` + `man_group`
`id`
`girl_id`
`man_saw`
  • Вопрос задан
  • 558 просмотров
Пригласить эксперта
Ответы на вопрос 1
slashinin
@slashinin
Задачи для PHP https://justcoding.ru
Укажите индексы в порядке их использования в условии WHERE, вынесите выборку полей в отдельный запрос, а затем его отсортируйте.

SELECT ... FROM (SELECT .... WHERE `man_id` = 1 AND `man_where` = 'inbox' AND `man_group` = 1) as table ORDER BY `id` DESC


Под запрос внутри FROM будет выполнен в первую очередь с использованием индексов
man_id, man_where, man_group
Главное, укажите эти индексы в таком же порядке.

Затем результат будет отсортирован с использование первичного индекса.
Должно помочь.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы