В принципе всё это есть в доке, но всё же народная мудрость говорит, что "повторение мать учения". Иногда полезно повторить, в т.ч. для себя.

И так, о сферических конях...
Индексы:
- В теории, наивысшая скорость выборки будет, если все поля в запросе есть в используемом индексе. PRIMARY индекс наиболее предпочтителен. (в EXPLAIN такие запросы имеют метки "Using where" и "Using index")
- Используемые индексы должны быть в RAM. (в т.ч. поэтому иногда применяют их предварительную загрузку в буфер, чтобы первый юзер не ждал долго)
- Индекс должен начинаться с поля, в котором разнообразие значений наименьшее. Второе - больше, третье - ещё больше и т.д.
Например: В Вашем примере наиболее правильным идексом будет вероятно (man_where, man_group, man_id). Но если у Вас будет задача выбрать NN записей из десятков тысяч найденных, то попробуйте добавить поля сортировки, что-то вроде (man_where, man_group, man_id, date, id) - это может ускорить выборку на 1-2 порядка за счёт исключения создания индекса сортировки (но увеличит затраты на изменение БД, естественно, и требование к размеру RAM).
- Порядок ASC быстрее, чем DESC.
- Индексы с числовыми полями быстрее, чем строковые.
- Стоит помнить, что в InnoDB PRIMARY-индекс определяет физическое расположение записей. Поэтому, наивысшая скорость добавления записей будет, если поля имеют последовательные значения.
- В сложных запросах оптимизатор иногда не справляется со своей задачей. В таких случаях ему нужно помочь в конкретном запросе (use index и т.п.). Оптимизация таблиц также иногда помогает.
- Полнотекстовый поиск по индексу может ускорить выборку на порядок и более (если смириться с ограничениями и кривостью).
Прочее:
- Наивысшая скорость выборки будет если все индексы и все данные будут в RAM.
- Если таблицы, используемые в запросе, изменяются много реже, чем читаются (на 1-2 порядка), то стоит использовать кеш запросов. Это ускорит получение данных в несколько раз и заметно уменьшит нагрузку на движок.
- Для не очень ответственных систем нужно отключить сброс каждой транзакции на диск. Это увеличит скорость добавления/изменения записей на порядок-два (в пределе до десятков тысяч/сек). Применять нужно только на относительно надёжном оборудовании и/или смириться с потерей пары-другой секунд изменений БД в случае сбоя.
- Несколько последовательных изменений завёрнутые в транзакционные рамки выполнятся быстрее, чем по отдельности. В т.ч. это надёжнее в плане целостности данных.
- Самый быстрый способ вставки строк - INSERT с множественными значениями.
- Не правильные/оптимальные настройки движка могут замедлить его работу от 10-20% до нескольких раз.
Структура:
- Денормализация больших данных почти всегда плохо. В основном это связано с работой с диском, но много "мусора" в RAM это тоже плохо. Денормализация небольших данных может ускорить выборку, если поле используется в условиях выборки.
- Для больших данных имеет смысл разбивать таблицы на части, согласно логике доступа к ним. Это позволит более эффективно использовать RAM (где только актуальные данные) и ускорить выборку актуальных, особенно в режиме DESC.
Например: В Вашем случае маловероятно, что юзеров будет интересовать переписка старше 1 месяца при каждом просмотре. Поэтому имеет смысл подумать над вариантом: 1 месяц это актуальные данные, остальное - архив. Вероятно, что запросов в архив будет на 2-3 порядка меньше, чем актуальных и их можно выдавать по требованию, не напрягаясь по поводу времени выборки (в разумных пределах, конечно).
- Обработка однобайтных кодировок быстрее, чем многобайтных.
- Партицирование стоит использовать для очень больших (сотни-тысячи гигов) и реально секционированных данных для запросов. В остальных случаях они бесполезны или вредны.
Ну, как-то так. Если что-то не сказал - спрашивайте, отвечу если знаю.
_____________
Рекламка / ad.pesow.com Хрень / mr-1.ru