В своем веб-приложении я создал внутреннюю систему обмена сообщениями. Я хочу разместить ссылку «предыдущий» и «следующий» на каждой странице (где пользователь просматривает сообщение).
Чтобы получить следующий и предыдущий идентификатор, я выполняю два запроса:
Для предыдущего:
SELECT id FROM pages WHERE (id<$requestedPageId) ORDER BY id DESC LIMIT 1
А для следующего:
SELECT id FROM pages WHERE (id>$requestedPageId) ORDER BY id LIMIT 1
EXPLAIN говорит, что типом запроса является "диапазон", а в столбце строк указано, что он будет проверять все строки, у которых идентификатор больше или меньше идентификатора страницы (большое число). В дополнительной строке написано «Использование где».
Кажется, MySQL игнорирует, что я хочу только одну строку. Разве MySQL не достаточно умен, чтобы оптимизировать такого рода запросы, чтобы он находил строку для страницы и искал первую соответствующую строку назад / вперед?
Есть ли лучший способ получить идентификатор следующей и предыдущей страницы?
Дополнительные примечания:
- Эта проблема, по-видимому, существует при каждом запросе типа ORDER BY LIMIT (например, когда я разбиваю длинный список на несколько страниц).
- Где предложение не такое простое (я хочу разрешить пользователю доступ к следующей / предыдущей странице, к которой у него есть права доступа. Однако присоединений нет.)
- Все столбцы появляются в ГДЕ проиндексированы (id является первичным ключом)
- переменные защищены от инъекций.
EDIT1:
Итак, запрос, который я сейчас использую:
SELECT id
FROM reports
WHERE (id<$requestedPageId) AND ((isPublic=1) OR (recipientId=$recipient))
ORDER BY id DESC
LIMIT 1
Или когда я перефакторинг, как ответ сказал:
SELECT MAX(id)
FROM reports
WHERE (id<$requestedPageId) AND ((isPublic=1) OR (recipientId=$recipient))