Предположим, в иллюстративных целях вы используете библиотеку, используя простую таблицу книг MySQL с тремя столбцами:
(идентификатор, название, статус)
- id - это первичный ключ
- название название книги
- status может быть перечислением, описывающим текущее состояние книги (например, ДОСТУПНО, ПРОВЕРЕНО, ОБРАБОТАНО, ОТСУТСТВУЕТ)
Простой запрос, чтобы сообщить, сколько книг попадает в каждое состояние:
SELECT status, COUNT(*) FROM books GROUP BY status
или чтобы узнать, сколько книг доступно:
SELECT COUNT(*) FROM books WHERE status = "AVAILABLE"
Однако, как только таблица увеличится до миллионов строк, выполнение этих запросов займет несколько секунд. Добавление индекса в столбец «status», похоже, не меняет моего опыта.
Помимо периодического кэширования результатов или явного обновления сводной информации в отдельной таблице каждый раз, когда книга меняет состояние (с помощью триггеров или другого механизма), существуют ли какие-либо методы для ускорения таких запросов? Кажется, что запросы COUNT заканчиваются просмотром каждой строки, и (не зная больше деталей) я немного удивлен, что эту информацию нельзя каким-то образом определить из индекса.
UPDATE
Используя образец таблицы (с индексированным столбцом «status») с 2 миллионами строк, я провел сравнительный анализ запроса GROUP BY. Используя механизм хранения InnoDB, запрос занимает 3,0 - 3,2 секунды на моем компьютере. Используя MyISAM, запрос занимает 0,9 - 1,1 секунды. В обоих случаях не было существенной разницы между количеством (*), количеством (статусом) или количеством (1).
MyISAM по общему признанию немного быстрее, но мне было любопытно посмотреть, есть ли способ заставить эквивалентный запрос выполняться намного быстрее (например, 10-50 мс - достаточно быстро, чтобы вызываться на каждом запрос веб-страницы для сайта с низким трафиком) без лишних затрат на кэширование и триггеры. Похоже, что ответ «нет возможности быстро выполнить прямой запрос», чего я и ожидал - я просто хотел убедиться, что я не пропустил простой вариант.