Создайте индекс, который содержит эти два поля в следующем порядке (followed_id, created_at)
Теперь, насколько велик большой, о котором мы здесь говорим? Если это будет порядка миллионов .. Как насчет чего-то вроде следующего ...
Создание индекса по ключам followed_id, created_at, id
(Это может измениться в зависимости от полей в select, where и order by. Я сделал это специально для вашего вопроса)
SELECT relationships.*
FROM relationships
JOIN (SELECT id
FROM relationships
WHERE followed_id = 1
ORDER BY created_at
LIMIT 10 OFFSET 10) itable
ON relationships.id = itable.id
ORDER BY relationships.created_at
Объяснение даст это:
+----+-------------+---------------+------+---------------+-------------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+---------------+-------------+---------+------+------+-----------------------------------------------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
| 2 | DERIVED | relationships | ref | sample_rel2 | sample_rel2 | 5 | | 1 | Using where; Using index |
+----+-------------+---------------+------+---------------+-------------+---------+------+------+-----------------------------------------------------+
Если вы внимательно изучите, подзапрос, содержащий предложения порядка, лимита и смещения, будет работать с индексом напрямую, а не с таблицей, и, наконец, объединится с таблицей, чтобы получить 10 записей.
Это имеет значение, когда в какой-то момент ваш запрос делает вызов, такой как limit 10 offset 10000
. Он извлечет все 10000 записей из таблицы и извлечет первые 10. Этот трюк должен ограничить обход только индексом.
Важное примечание: Я проверял это в MySQL. Другая база данных может иметь незначительные различия в поведении, но концепция остается верной, несмотря ни на что.